MachineSystem::MachineSystem(int width, int height, int hPegs, int vPegs, cpVect position) : parts(hPegs*vPegs), attachments((hPegs*vPegs), std::vector<Attachment *>(hPegs*vPegs, NULL)), space(cpSpaceNew()), nMachines(0), nAttachments(0) { cpSpaceSetIterations(space, 20); gridSpacing = cpv((float)width/(hPegs + 1), (float)height/(vPegs + 1)); size = cpv(hPegs, vPegs); body = cpBodyNewStatic(); cpBodySetPos(body, position); cpShape *wallShape = cpSegmentShapeNew(body, cpv(-width/2, height/2), cpv(width/2, height/2), .5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(-width/2, -height/2), cpv(+width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(-width/2, +height/2), cpv(-width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(+width/2, +height/2), cpv(+width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); inputMachinePosition = cpv(-1,-1); outputMachinePosition = cpv(-1,-1); }
void LevelGrid::InitializeLevelPhysics(void) { // Fetch the physics space cpSpace *space = this->m_Engine->GetWorld()->GetSpace(); // Add the physics body this->m_Body = cpBodyNewStatic(); // Add the physics shapes for (int i = 0 ; i < this->m_NumY - 1 ; ++i) { hgeVector *vec = this->m_LeftLevelVertices[i]; hgeVector *nvec = this->m_LeftLevelVertices[i + 1]; cpShape *shape = cpSegmentShapeNew(this->m_Body, cpv(vec->x, vec->y), cpv(nvec->x, nvec->y), 0.0f); shape->e = 1.0; shape->u = 1.0; shape->collision_type = COLLISION_TYPE_LEVEL; cpSpaceAddStaticShape(space, shape); cpBodyActivateStatic(this->m_Body, shape); this->m_Shapes.push_back(shape); } for (int i = 0 ; i < this->m_NumY - 1 ; ++i) { hgeVector *vec = this->m_RightLevelVertices[i]; hgeVector *nvec = this->m_RightLevelVertices[i + 1]; cpShape *shape = cpSegmentShapeNew(this->m_Body, cpv(vec->x, vec->y), cpv(nvec->x, nvec->y), 0.0f); shape->e = 1.0; shape->u = 1.0; shape->collision_type = COLLISION_TYPE_LEVEL; cpSpaceAddStaticShape(space, shape); cpBodyActivateStatic(this->m_Body, shape); this->m_Shapes.push_back(shape); } // Create the activator physics shapes for (int i = 0 ; i < this->m_NumActivators ; ++i) { Activator *activator = this->m_Activators[i]; // Create the cpVects cpVect *verts = (cpVect*) malloc(sizeof(cpVect) * 4); verts[3].x = activator->Vertices[0].x; verts[3].y = activator->Vertices[0].y; verts[2].x = activator->Vertices[1].x; verts[2].y = activator->Vertices[1].y; verts[1].x = activator->Vertices[2].x; verts[1].y = activator->Vertices[2].y; verts[0].x = activator->Vertices[3].x; verts[0].y = activator->Vertices[3].y; // Create and add the poly shape cpShape *shape = cpPolyShapeNew(this->m_Body, 4, verts, cpvzero); shape->e = 1.0; shape->u = 1.0; shape->sensor = true; shape->collision_type = COLLISION_TYPE_ACTIVATOR; shape->data = activator; cpSpaceAddStaticShape(space, shape); cpBodyActivateStatic(this->m_Body, shape); this->m_Shapes.push_back(shape); free(verts); } }
static cpSpace * init(void) { space = cpSpaceNew(); cpSpaceSetGravity(space, cpv(0, -600)); cpBody *body; cpShape *shape; // We create an infinite mass rogue body to attach the line segments too // This way we can control the rotation however we want. rogueBoxBody = cpBodyNew(INFINITY, INFINITY); cpBodySetAngVel(rogueBoxBody, 0.4f); // Set up the static box. cpVect a = cpv(-200, -200); cpVect b = cpv(-200, 200); cpVect c = cpv( 200, 200); cpVect d = cpv( 200, -200); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, a, b, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, b, c, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, c, d, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(rogueBoxBody, d, a, 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat mass = 1; cpFloat width = 60; cpFloat height = 30; // Add the bricks. for(int i=0; i<3; i++){ for(int j=0; j<7; j++){ body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForBox(mass, width, height))); cpBodySetPos(body, cpv(i*60 - 150, j*30 - 150)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.7f); } } return space; }
static cpSpace * init(void) { staticBody = cpBodyNew(INFINITY, INFINITY); cpResetShapeIdCounter(); space = cpSpaceNew(); cpSpaceResizeActiveHash(space, 30.0f, 1000); space->iterations = 10; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; for(int i=0; i<50; i++){ cpBody *body = add_box(10.0, 1.0); cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, body, cpvzero, cpvzero)); pivot->biasCoef = 0.0f; // disable joint correction pivot->maxForce = 1000.0f; // emulate linear friction cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(staticBody, body, 0.0f, 1.0f)); gear->biasCoef = 0.0f; // disable joint correction gear->maxForce = 5000.0f; // emulate angular friction } // We joint the tank to the control body and control the tank indirectly by modifying the control body. tankControlBody = cpBodyNew(INFINITY, INFINITY); tankBody = add_box(15.0, 10.0); cpConstraint *pivot = cpSpaceAddConstraint(space, cpPivotJointNew2(tankControlBody, tankBody, cpvzero, cpvzero)); pivot->biasCoef = 0.0f; // disable joint correction pivot->maxForce = 10000.0f; // emulate linear friction cpConstraint *gear = cpSpaceAddConstraint(space, cpGearJointNew(tankControlBody, tankBody, 0.0f, 1.0f)); gear->biasCoef = 1.0f; // limit angular correction rate gear->maxBias = 1.0f; // limit angular correction rate gear->maxForce = 500000.0f; // emulate angular friction return space; }
static cpSpace * init(void) { ChipmunkDemoMessageString = "One way platforms are trivial in Chipmunk using a very simple collision callback."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 10); cpSpaceSetGravity(space, cpv(0, -100)); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // Add our one way segment shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-100), cpv(160,-100), 10.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLISION_TYPE_ONE_WAY); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // We'll use the data pointer for the OneWayPlatform struct platformInstance.n = cpv(0, 1); // let objects pass upwards cpShapeSetUserData(shape, &platformInstance); // Add a ball to test it out cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); cpBodySetPosition(body, cpv(0, -200)); cpBodySetVelocity(body, cpv(0, 170)); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.9f); cpShapeSetCollisionType(shape, 2); cpCollisionHandler *handler = cpSpaceAddWildcardHandler(space, COLLISION_TYPE_ONE_WAY); handler->preSolveFunc = PreSolve; return space; }
static cpSpace * init(void) { cpSpace *space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -GRAVITY); // space->sleepTimeThreshold = 1000; space->enableContactGraph = cpTrue; cpBody *body, *staticBody = space->staticBody; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; // Set up the player cpFloat radius = 25.0f; body = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY)); body->p = cpv(0, -200); body->velocity_func = playerUpdateVelocity; playerBody = body; shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); shape->e = 0.0f; shape->u = 0.0f; shape->collision_type = 1; playerShape = shape; // Add some boxes to jump on for(int i=0; i<6; i++){ for(int j=0; j<3; j++){ body = cpSpaceAddBody(space, cpBodyNew(4.0f, INFINITY)); body->p = cpv(100 + j*60, -200 + i*60); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 50, 50)); shape->e = 0.0f; shape->u = 0.7f; } } return space; }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Sticky collisions using the cpArbiter data pointer."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 10); cpSpaceSetGravity(space, cpv(0, -1000)); cpSpaceSetCollisionSlop(space, 2.0); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv(-340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv( 340,-260), cpv( 340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv( 340,-260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340, 260), cpv( 340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); for(int i=0; i<200; i++){ cpFloat mass = 0.15f; cpFloat radius = 10.0f; cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero))); cpBodySetPos(body, cpv(cpflerp(-150.0f, 150.0f, frand()), cpflerp(-150.0f, 150.0f, frand()))); cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius + STICK_SENSOR_THICKNESS, cpvzero)); cpShapeSetFriction(shape, 0.9f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); } cpSpaceAddCollisionHandler(space, COLLIDE_STICK_SENSOR, COLLIDE_STICK_SENSOR, NULL, StickyPreSolve, NULL, StickySeparate, NULL); return space; }
static cpSpace * init(void) { cpSpace *space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -GRAVITY); // space->sleepTimeThreshold = 1000; cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // Set up the player body = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY)); body->p = cpv(0, -200); body->velocity_func = playerUpdateVelocity; playerBody = body; shape = cpSpaceAddShape(space, cpBoxShapeNew2(body, cpBBNew(-15.0, -27.5, 15.0, 27.5), 10.0)); // shape = cpSpaceAddShape(space, cpSegmentShapeNew(playerBody, cpvzero, cpv(0, radius), radius)); shape->e = 0.0f; shape->u = 0.0f; shape->type = 1; playerShape = shape; // Add some boxes to jump on for(int i=0; i<6; i++){ for(int j=0; j<3; j++){ body = cpSpaceAddBody(space, cpBodyNew(4.0f, INFINITY)); body->p = cpv(100 + j*60, -200 + i*60); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 50, 50, 0.0)); shape->e = 0.0f; shape->u = 0.7f; } } return space; }
static cpSpace * init(void) { cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -100)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // Add lots of boxes. for(int i=0; i<14; i++){ for(int j=0; j<=i; j++){ body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForBox(1.0f, 30.0f, 30.0f))); cpBodySetPosition(body, cpv(j*32 - i*16, 300 - i*32)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 30.0f, 30.0f, 0.5f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.8f); } } // Add a ball to make things more interesting cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); cpBodySetPosition(body, cpv(0, -240 + radius+5)); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.9f); return space; }
static cpSpace * init(void) { QUERY_START = cpvzero; space = cpSpaceNew(); cpSpaceSetIterations(space, 5); { // add a fat segment cpFloat mass = 1.0f; cpFloat length = 100.0f; cpVect a = cpv(-length/2.0f, 0.0f), b = cpv(length/2.0f, 0.0f); cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b))); cpBodySetPos(body, cpv(0.0f, 100.0f)); cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 20.0f)); } { // add a static segment cpSpaceAddShape(space, cpSegmentShapeNew(cpSpaceGetStaticBody(space), cpv(0, 300), cpv(300, 0), 0.0f)); } { // add a pentagon cpFloat mass = 1.0f; const int NUM_VERTS = 5; cpVect verts[NUM_VERTS]; for(int i=0; i<NUM_VERTS; i++){ cpFloat angle = -2*M_PI*i/((cpFloat) NUM_VERTS); verts[i] = cpv(30*cos(angle), 30*sin(angle)); } cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, NUM_VERTS, verts, cpvzero))); cpBodySetPos(body, cpv(50.0f, 50.0f)); cpSpaceAddShape(space, cpPolyShapeNew(body, NUM_VERTS, verts, cpvzero)); } { // add a circle cpFloat mass = 1.0f; cpFloat r = 20.0f; cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, r, cpvzero))); cpBodySetPos(body, cpv(100.0f, 100.0f)); cpSpaceAddShape(space, cpCircleShapeNew(body, r, cpvzero)); } return space; }
static cpSpace * init(void) { cpResetShapeIdCounter(); space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -100); cpBody *body, *staticBody = &space->staticBody; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; // Add our one way segment shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-100), cpv(160,-100), 10.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->collision_type = 1; shape->layers = NOT_GRABABLE_MASK; // We'll use the data pointer for the OneWayPlatform struct platformInstance.n = cpv(0, 1); // let objects pass upwards platformInstance.passThruList = cpArrayNew(0); shape->data = &platformInstance; // Add a ball to make things more interesting cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); body->p = cpv(0, -200); body->v = cpv(0, 170); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); shape->e = 0.0f; shape->u = 0.9f; shape->collision_type = 2; cpSpaceAddCollisionHandler(space, 1, 2, NULL, preSolve, NULL, NULL, NULL); return space; }
ETERM *space_add_boundaries(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *lower_leftp = erl_element(2, argp); ETERM *lower_rightp = erl_element(3, argp); ETERM *upper_leftp = erl_element(4, argp); ETERM *upper_rightp = erl_element(5, argp); ETERM *collision_categoryp = erl_element(6, argp); ETERM *datap = erl_element(7, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); cpVect lowerLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_leftp)), ERL_FLOAT_VALUE(erl_element(2, lower_leftp))); cpVect lowerRight = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_rightp)), ERL_FLOAT_VALUE(erl_element(2, lower_rightp))); cpVect upperLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_leftp)), ERL_FLOAT_VALUE(erl_element(2, upper_leftp))); cpVect upperRight = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_rightp)), ERL_FLOAT_VALUE(erl_element(2, upper_rightp))); // get the static body that comes with the space cpBody *static_body = cpSpaceGetStaticBody(s->space); erlmunk_body_data *data = malloc(sizeof(erlmunk_body_data)); data->id = BOUNDARY_BODY_ID; data->term = erl_copy_term(datap); cpBodySetUserData(static_body, (cpDataPointer) data); // bottom cpShape *bottomBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, lowerRight, 0.0f); cpShapeSetCollisionType(bottomBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, bottomBoundaryShape); // top cpShape *topBoundaryShape = cpSegmentShapeNew(static_body, upperLeft, upperRight, 0.0f); cpShapeSetCollisionType(topBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, topBoundaryShape); // left cpShape *leftBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, upperLeft, 0.0f); cpShapeSetCollisionType(leftBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, leftBoundaryShape); // right cpShape *rightBoundaryShape = cpSegmentShapeNew(static_body, lowerRight, upperRight, 0.0f); cpShapeSetCollisionType(rightBoundaryShape, ERL_INT_VALUE(collision_categoryp)); cpSpaceAddShape(s->space, rightBoundaryShape); return NULL; }
static cpSpace * init(void) { cpResetShapeIdCounter(); space = cpSpaceNew(); space->iterations = 30; cpSpaceResizeStaticHash(space, 40.0f, 1000); cpSpaceResizeActiveHash(space, 40.0f, 1000); space->gravity = cpv(0, -100); space->sleepTimeThreshold = 0.5f; cpBody *body, *staticBody = &space->staticBody; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; // Add lots of boxes. for(int i=0; i<14; i++){ for(int j=0; j<=i; j++){ body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForBox(1.0f, 30.0f, 30.0f))); body->p = cpv(j*32 - i*16, 300 - i*32); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 30.0f, 30.0f)); shape->e = 0.0f; shape->u = 0.8f; } } // Add a ball to make things more interesting cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); body->p = cpv(0, -240 + radius+5); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); shape->e = 0.0f; shape->u = 0.9f; return space; }
bool PhysicsShapeEdgeSegment::init(const Point& a, const Point& b, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/) { do { CC_BREAK_IF(!PhysicsShape::init(Type::EDGESEGMENT)); cpShape* shape = cpSegmentShapeNew(_info->getSharedBody(), PhysicsHelper::point2cpv(a), PhysicsHelper::point2cpv(b), PhysicsHelper::float2cpfloat(border)); CC_BREAK_IF(shape == nullptr); _info->add(shape); _mass = PHYSICS_INFINITY; _moment = PHYSICS_INFINITY; _center = a.getMidpoint(b); setMaterial(material); return true; } while (false); return false; }
WorldShape_t *worldShape_createSegment(vec2_t a, vec2_t b, GLMFloat aThickness) { WorldShape_t *out = obj_create_autoreleased(&Class_WorldShape); out->cpShape = cpSegmentShapeNew(NULL, VEC2_TO_CPV(a), VEC2_TO_CPV(b), aThickness); out->cpShape->data = out; return out; }
bool PhysicsShapeEdgeChain::init(const Vec2* points, int count, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/) { cpVect* vec = nullptr; do { _type = Type::EDGECHAIN; vec = new (std::nothrow) cpVect[count]; PhysicsHelper::points2cpvs(points, vec, count); int i = 0; for (; i < count - 1; ++i) { auto shape = cpSegmentShapeNew(s_sharedBody, vec[i], vec[i + 1], border); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); addShape(shape); } CC_SAFE_DELETE_ARRAY(vec); CC_BREAK_IF(i < count - 1); _mass = PHYSICS_INFINITY; _moment = PHYSICS_INFINITY; setMaterial(material); return true; } while (false); CC_SAFE_DELETE_ARRAY(vec); return false; }
static void post_step_body_replace_shapes(cpSpace *space, cpBody *body, void *data) { Body_data *pa = cpBodyGetUserData(body); int length = pa->x_values->len; cpBodyEachShape(body, (cpBodyShapeIteratorFunc) free_shape, NULL); cpSpaceReindexShapesForBody(space, body); //fprintf(stderr, "0Made it this far.\n"); for (int index = 1; index < length; index++) { cpFloat x = g_array_index(pa->x_values, cpFloat, index); cpFloat y = g_array_index(pa->y_values, cpFloat, index); cpShape *seg = cpSegmentShapeNew(body, cpv(x,y), cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1)), CRAYON_RADIUS); //fprintf(stderr, "1Made it this far.\n"); cpShapeSetFriction(seg, CRAYON_FRICTION); //fprintf(stderr, "2Made it this far.\n"); //cpShapeSetElasticity(cpShape *shape, cpFloat value)? cpSpaceAddShape(space, seg); //fprintf(stderr, "3Made it this far.\n"); } cpSpaceReindexShapesForBody(space, body); }
cpSpace *Slice::Init() { ChipmunkDemo::Init(); message = "Hold right bottom corner and slice with touch."; space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -500)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-1000,-240), cpv(1000,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); cpFloat width = 200.0f; cpFloat height = 300.0f; cpFloat mass = width*height*DENSITY; cpFloat moment = cpMomentForBox(mass, width, height); body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height, 0.0)); cpShapeSetFriction(shape, 0.6f); return space; }
static cpSpace *initSpace(void) { int i; cpBody *staticBody; cpShape *shape; cpVect cannonPos; cpResetShapeIdCounter(); g_Space = cpSpaceNew(); g_Space->iterations = 30; g_Space->gravity = cpv(0, -300); staticBody = &g_Space->staticBody; shape = cpSpaceAddShape(g_Space, cpSegmentShapeNew(staticBody, cpv(-400,-290), cpv(-400,300), 0.0f)); shape->e = 1.0f; shape->u = 0.0f; shape->collision_type = PLATFORM_TYPE; cannonPos = cpv(-350, -215); g_Cannon = createCannon(cannonPos, 30.0f, 6.0f); g_Cannon->ai = 0; for (i = 0; i < MAX_PROJECTILES; ++i) { g_Cannon->ammo[i] = createProjectile(6.0f, 1.0f); } platforms[0] = createPlatform(staticBody, cpv(-390, -240), cpv(1600, -240), 10.0f); fprintf(stderr, "Loading dominoes disabled\n"); InitializeDominoes(); cpSpaceAddCollisionHandler(g_Space, PROJECTILE_TYPE, DOMINO_OBJECT_TYPE, NULL, NULL, postSolveProjectileDomino, NULL, NULL); return g_Space; }
bool PhysicsShapeEdgeBox::init(const Size& size, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/, const Point& offset/*= Point(0, 0)*/) { do { CC_BREAK_IF(!PhysicsShape::init(Type::EDGEBOX)); cpVect vec[4] = {}; vec[0] = PhysicsHelper::point2cpv(Point(-size.width/2+offset.x, -size.height/2+offset.y)); vec[1] = PhysicsHelper::point2cpv(Point(+size.width/2+offset.x, -size.height/2+offset.y)); vec[2] = PhysicsHelper::point2cpv(Point(+size.width/2+offset.x, +size.height/2+offset.y)); vec[3] = PhysicsHelper::point2cpv(Point(-size.width/2+offset.x, +size.height/2+offset.y)); int i = 0; for (; i < 4; ++i) { cpShape* shape = cpSegmentShapeNew(_info->getSharedBody(), vec[i], vec[(i+1)%4], PhysicsHelper::float2cpfloat(border)); CC_BREAK_IF(shape == nullptr); _info->add(shape); } CC_BREAK_IF(i < 4); _offset = offset; _mass = PHYSICS_INFINITY; _moment = PHYSICS_INFINITY; setMaterial(material); return true; } while (false); return false; }
bool PhysicsShapeEdgeBox::init(const Size& size, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/, const Vec2& offset/*= Vec2(0, 0)*/) { do { _type = Type::EDGEBOX; cpVect vec[4] = {}; vec[0] = PhysicsHelper::point2cpv(Vec2(-size.width/2+offset.x, -size.height/2+offset.y)); vec[1] = PhysicsHelper::point2cpv(Vec2(+size.width/2+offset.x, -size.height/2+offset.y)); vec[2] = PhysicsHelper::point2cpv(Vec2(+size.width/2+offset.x, +size.height/2+offset.y)); vec[3] = PhysicsHelper::point2cpv(Vec2(-size.width/2+offset.x, +size.height/2+offset.y)); int i = 0; for (; i < 4; ++i) { auto shape = cpSegmentShapeNew(s_sharedBody, vec[i], vec[(i + 1) % 4], border); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); addShape(shape); } CC_BREAK_IF(i < 4); _mass = PHYSICS_INFINITY; _moment = PHYSICS_INFINITY; setMaterial(material); return true; } while (false); return false; }
int l_physics_newShape(lua_State* state) { l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a space"); l_tools_checkUserDataPlusErrMsg(state, 2, "You must provide a body"); l_physics_PhysicsData* physics = (l_physics_PhysicsData*)lua_touserdata(state, 1); l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 2); float x1 = l_tools_toNumberOrError(state, 3); float y1 = l_tools_toNumberOrError(state, 4); float x2 = l_tools_toNumberOrError(state, 5); float y2 = l_tools_toNumberOrError(state, 6); float radius = l_tools_toNumberOrError(state, 7); moduleData.shape = (l_physics_Shape*)lua_newuserdata(state, sizeof(l_physics_Shape)); moduleData.shape->physics = malloc(sizeof(physics_PhysicsData)); moduleData.shape->physics = physics->physics; moduleData.shape->shape = cpSpaceAddShape(physics->physics->space, cpSegmentShapeNew(body->body, cpv(x1, y1), cpv(x2, y2), radius)); lua_rawgeti(state, LUA_REGISTRYINDEX, moduleData.shapeMT); lua_setmetatable(state, -2); return 1; }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Right click and drag to change the blocks's shape."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -500)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat width = 50.0f; cpFloat height = 70.0f; cpFloat mass = width*height*DENSITY; cpFloat moment = cpMomentForBox(mass, width, height); body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height)); cpShapeSetFriction(shape, 0.6f); return space; }
bool PhysicsShapeEdgeSegment::init(const Vec2& a, const Vec2& b, const PhysicsMaterial& material/* = MaterialDefault*/, float border/* = 1*/) { do { _type = Type::EDGESEGMENT; auto shape = cpSegmentShapeNew(s_sharedBody, PhysicsHelper::point2cpv(a), PhysicsHelper::point2cpv(b), border); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); addShape(shape); _mass = PHYSICS_INFINITY; _moment = PHYSICS_INFINITY; setMaterial(material); return true; } while (false); return false; }
void ChipmunkTestLayer::initPhysics() { #if CC_ENABLE_CHIPMUNK_INTEGRATION // init chipmunk //cpInitChipmunk(); _space = cpSpaceNew(); //_space->gravity = cpv(0, -100); _space->gravity = cpv(0, 0); // // rogue shapes // We have to free them manually // // bottom _walls[0] = cpSegmentShapeNew( _space->staticBody, cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y), cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), 0.0f); // top _walls[1] = cpSegmentShapeNew( _space->staticBody, cpv(VisibleRect::leftTop().x, VisibleRect::leftTop().y), cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f); // left _walls[2] = cpSegmentShapeNew( _space->staticBody, cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y), cpv(VisibleRect::leftTop().x,VisibleRect::leftTop().y), 0.0f); // right _walls[3] = cpSegmentShapeNew( _space->staticBody, cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f); for( int i=0;i<4;i++) { _walls[i]->e = 1.0f; _walls[i]->u = 1.0f; cpSpaceAddStaticShape(_space, _walls[i] ); } // Physics debug layer _debugLayer = PhysicsDebugNode::create(_space); this->addChild(_debugLayer, Z_PHYSICS_DEBUG); #endif }
void Ring::init(float backBoardLength, float groundLength, float ringSize, float e, float u) { /* cpBody* backBoardBody; cpShape* backBoardShape; cpShape* groundShape; cpShape* ring1Shape; cpShape* ring2Shape;*/ int easy = -3; // 난이도 하락시키는 직선높이 차이 this->ringSize = ringSize; backBoardBody = cpBodyNew(INFINITY, INFINITY); setPosition(cpv(57, 250)); //backBoardBody->p = cpv(60, 250); // 50 //backBoardBody->p = cpv(60, 100); backBoardShape = cpSegmentShapeNew(backBoardBody, cpv(0,0), cpv(0, backBoardLength), 1.f); // CCLog("backboard shape %x", backBoardShape); backBoardShape->e = BACKBOARD_E; backBoardShape->u = u; groundShape = cpSegmentShapeNew(backBoardBody, cpv(0,0), cpv(groundLength - 2.f, easy), 1.f); // CCLog("ground shape %x", groundShape); groundShape->e = e / 3.f; groundShape->u = u; subObject = cpSegmentShapeNew(backBoardBody, cpv(groundLength -2.f, easy), cpv(groundLength - 2.f, -10.f), 1.f); // 길다란 보조 장치, 자연스러운 공경로를 위해 // CCLog("subobject shape %x", subObject); subObject->e = e; subObject->u = u; ring1Shape = cpCircleShapeNew(backBoardBody, 1.f, cpv(groundLength, easy )); // CCLog("ring1 shape %x", ring1Shape); ring1Shape->e = e / 3.f; ring1Shape->u = u; ring2Shape = cpCircleShapeNew(backBoardBody, 1.f, cpv(groundLength + ringSize, 0.f)); // CCLog("ring2 shape %x", ring2Shape); ring2Shape->e = e; ring2Shape->u = u; ring3Shape = cpCircleShapeNew(backBoardBody, 1.f, cpv((2*groundLength + ringSize) / 2.f, 0.f)); // CCLog("ring3 shape %x", ring2Shape); ring3Shape->e = e; ring3Shape->u = u; }
void HelloWorld::initPhysic() { #if CC_ENABLE_CHIPMUNK_INTEGRATION //启动重力加速度,系统会定时调用didAccelerate setAccelerometerEnabled(true); m_pSpace = cpSpaceNew(); m_pSpace->gravity = cpv(0, -100); // // rogue shapes // We have to free them manually // // bottom m_pWalls[0] = cpSegmentShapeNew( m_pSpace->staticBody, cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y), cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), 0.0f); // top m_pWalls[1] = cpSegmentShapeNew( m_pSpace->staticBody, cpv(VisibleRect::leftTop().x, VisibleRect::leftTop().y), cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f); // left m_pWalls[2] = cpSegmentShapeNew( m_pSpace->staticBody, cpv(VisibleRect::leftBottom().x,VisibleRect::leftBottom().y), cpv(VisibleRect::leftTop().x,VisibleRect::leftTop().y), 0.0f); // right m_pWalls[3] = cpSegmentShapeNew( m_pSpace->staticBody, cpv(VisibleRect::rightBottom().x, VisibleRect::rightBottom().y), cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f); for( int i=0;i<4;i++) { m_pWalls[i]->e = 1.0f; m_pWalls[i]->u = 1.0f; cpSpaceAddStaticShape(m_pSpace, m_pWalls[i] ); } // Physics debug layer m_pDebugLayer = CCPhysicsDebugNode::create(m_pSpace); this->addChild(m_pDebugLayer, Z_PHYSICS_DEBUG); #endif }
// adds a freestyle shape given a pointer to a an array of vertices and the number of vertices //returns a cpbody due to the many shapes associated with one body cpBody *core_add_freestyle_shape ( cpSpace * space, cpVect* verts , const int num_verts, Color *color, const double friction, const double elasticity, const double density, const int index ) { if ( num_verts <= 1 ) return NULL; // first determine center of mass of object cpVect center; core_freestyle_center ( verts, num_verts, ¢er ); // calculate mass and moment cpFloat mass = core_freestyle_mass ( verts, num_verts, density ); // dummy moment calculation cpFloat moment = core_freestyle_moment ( verts, num_verts, center, density ); cpBody *body = cpBodyNew ( mass, moment ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc)postStepAddBody, body, NULL ); cpBodySetPos ( body, center ); // set index of body // add body info to body BodyInfo * bi = body_info_new(num_verts); bi->index = index; bi->type = FREESTYLE_TYPE; bi->num_verts = num_verts; for ( int i = 0; i < num_verts; i++ ) { (bi->verts[i]).x = verts[i].x; (bi->verts[i]).y = verts[i].y; } bi->color->r = color->r; bi->color->g = color->g; bi->color->b = color->b; bi->friction = friction; bi->density = density; bi->elasticity = elasticity; body->data = bi; // add line segment collision shapes to body for ( int i = 0; i < num_verts - 1; i++ ) { cpVect offset_a = cpvmult ( cpvsub ( verts[i], center), 1.0 ); cpVect offset_b = cpvmult ( cpvsub ( verts[i+1], center), 1.0 ); cpShape * segment = cpSegmentShapeNew ( body, offset_a, offset_b, 0.1 ); cpSpaceAddPostStepCallback ( space, (cpPostStepFunc) postStepAddShape, segment, NULL); segment->u = friction; DrawShapeInfo *info = draw_shape_info_new (); info->color->r = color->r; info->color->g = color->g; info->color->b = color->b; segment->data = ( cpDataPointer ) info; } return body; }
void GameScene::createPhysicsBox(int x1, int y1, int x2, int y2, float elasticity, float friction, int collisionType) { cpShape* shape = nullptr; int start = shapes.size(); // create box as four segments shapes.push_back(cpSegmentShapeNew(space->staticBody, cpv(x1, y1), cpv(x1, y2), 0.0f)); shapes.push_back(cpSegmentShapeNew(space->staticBody, cpv(x1, y2), cpv(x2, y2), 0.0f)); shapes.push_back(cpSegmentShapeNew(space->staticBody, cpv(x2, y2), cpv(x2, y1), 0.0f)); shapes.push_back(cpSegmentShapeNew(space->staticBody, cpv(x2, y1), cpv(x1, y1), 0.0f)); for (int i = 0; i < 4; i++) { shapes[start + i]->e = elasticity; shapes[start + i]->u = friction; shapes[start + i]->collision_type = collisionType; cpSpaceAddStaticShape(space, shapes[start + i]); } }
static void make_leg(cpSpace *space, cpFloat side, cpFloat offset, cpBody *chassis, cpBody *crank, cpVect anchor) { cpVect a, b; cpShape *shape; cpFloat leg_mass = 1.0f; // make leg a = cpvzero, b = cpv(0.0f, side); cpBody *upper_leg = cpSpaceAddBody(space, cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b, 0.0f))); cpBodySetPosition(upper_leg, cpv(offset, 0.0f)); shape = cpSpaceAddShape(space, cpSegmentShapeNew(upper_leg, a, b, seg_radius)); cpShapeSetFilter(shape, cpShapeFilterNew(1, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES)); cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, upper_leg, cpv(offset, 0.0f), cpvzero)); // lower leg a = cpvzero, b = cpv(0.0f, -1.0f*side); cpBody *lower_leg = cpSpaceAddBody(space, cpBodyNew(leg_mass, cpMomentForSegment(leg_mass, a, b, 0.0f))); cpBodySetPosition(lower_leg, cpv(offset, -side)); shape = cpSpaceAddShape(space, cpSegmentShapeNew(lower_leg, a, b, seg_radius)); cpShapeSetFilter(shape, cpShapeFilterNew(1, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES)); shape = cpSpaceAddShape(space, cpCircleShapeNew(lower_leg, seg_radius*2.0f, b)); cpShapeSetFilter(shape, cpShapeFilterNew(1, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 1.0f); cpSpaceAddConstraint(space, cpPinJointNew(chassis, lower_leg, cpv(offset, 0.0f), cpvzero)); cpSpaceAddConstraint(space, cpGearJointNew(upper_leg, lower_leg, 0.0f, 1.0f)); cpConstraint *constraint; cpFloat diag = cpfsqrt(side*side + offset*offset); constraint = cpSpaceAddConstraint(space, cpPinJointNew(crank, upper_leg, anchor, cpv(0.0f, side))); cpPinJointSetDist(constraint, diag); constraint = cpSpaceAddConstraint(space, cpPinJointNew(crank, lower_leg, anchor, cpvzero)); cpPinJointSetDist(constraint, diag); }