/** * Pop the bubble splitting it into two bubbles. * No children are created if the bubble was too small. */ int bubble_pop(struct bubble *b, struct game *g) { if (b->l <= 1) { bubble_destroy(b); return 0; } double radius = cpCircleShapeGetRadius(&b->shape); cpVect pos = cpBodyGetPos(&b->body); cpVect vel = cpBodyGetVel(&b->body); bubble_remove(b, g); bubble_destroy(b); b = bubble_init(b, pos.x, pos.y, vel.x + 5, vel.y + 5, radius / 2, b->l - 1); if (!b) { ERR_TRACE(); return -1; } //b->events = b->events; if (bubble_add(b, g)) { ERR_TRACE(); return -1; } struct bubble *c = bubble_create(pos.x, pos.y, vel.x - 5, vel.y + 5, radius / 2, b->l - 1); if (!c) { ERR_TRACE(); return -1; } //c->events = b->events; if (bubble_add(c, g)) { ERR_TRACE(); return -1; } return 0; }
void PhysicsDebugDraw::drawShape(PhysicsShape& shape) { const Color4F fillColor(1.0f, 0.0f, 0.0f, 0.3f); const Color4F outlineColor(1.0f, 0.0f, 0.0f, 1.0f); for (auto it = shape._cpShapes.begin(); it != shape._cpShapes.end(); ++it) { cpShape *subShape = *it; switch ((*it)->klass_private->type) { case CP_CIRCLE_SHAPE: { float radius = PhysicsHelper::cpfloat2float(cpCircleShapeGetRadius(subShape)); Vec2 centre = PhysicsHelper::cpv2point(cpBodyGetPos(cpShapeGetBody(subShape))); Vec2 offset = PhysicsHelper::cpv2point(cpCircleShapeGetOffset(subShape)); Vec2 rotation(PhysicsHelper::cpv2point(cpBodyGetRot(cpShapeGetBody(subShape)))); centre += offset.rotate(rotation); static const int CIRCLE_SEG_NUM = 12; Vec2 seg[CIRCLE_SEG_NUM] = {}; for (int i = 0; i < CIRCLE_SEG_NUM; ++i) { float angle = (float)i * M_PI / (float)CIRCLE_SEG_NUM * 2.0f; Vec2 d(radius * cosf(angle), radius * sinf(angle)); seg[i] = centre + d; } _drawNode->drawPolygon(seg, CIRCLE_SEG_NUM, fillColor, 1, outlineColor); break; } case CP_SEGMENT_SHAPE: { cpSegmentShape *seg = (cpSegmentShape *)subShape; _drawNode->drawSegment(PhysicsHelper::cpv2point(seg->ta), PhysicsHelper::cpv2point(seg->tb), PhysicsHelper::cpfloat2float(seg->r==0 ? 1 : seg->r), outlineColor); break; } case CP_POLY_SHAPE: { cpPolyShape* poly = (cpPolyShape*)subShape; int num = poly->numVerts; Vec2* seg = new (std::nothrow) Vec2[num]; PhysicsHelper::cpvs2points(poly->tVerts, seg, num); _drawNode->drawPolygon(seg, num, fillColor, 1.0f, outlineColor); delete[] seg; break; } default: break; } } }
float PhysicsShapeCircle::calculateDefaultMoment() { auto shape = _cpShapes.front(); return _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : PhysicsHelper::cpfloat2float(cpMomentForCircle(_mass, 0, cpCircleShapeGetRadius(shape), cpCircleShapeGetOffset(shape))); }
float PhysicsShapeCircle::calculateDefaultMoment() { cpShape* shape = _info->getShapes().front(); return _mass == PHYSICS_INFINITY ? PHYSICS_INFINITY : PhysicsHelper::cpfloat2float(cpMomentForCircle(PhysicsHelper::float2cpfloat(_mass), 0, cpCircleShapeGetRadius(shape), cpCircleShapeGetOffset(shape))); }
void PhysicsDebugDraw::drawShape(PhysicsShape& shape) { for (auto it = shape._info->getShapes().begin(); it != shape._info->getShapes().end(); ++it) { cpShape *subShape = *it; switch ((*it)->klass_private->type) { case CP_CIRCLE_SHAPE: { float radius = PhysicsHelper::cpfloat2float(cpCircleShapeGetRadius(subShape)); Point centre = PhysicsHelper::cpv2point(cpBodyGetPos(cpShapeGetBody(subShape))) + PhysicsHelper::cpv2point(cpCircleShapeGetOffset(subShape)); static const int CIRCLE_SEG_NUM = 12; Point seg[CIRCLE_SEG_NUM] = {}; for (int i = 0; i < CIRCLE_SEG_NUM; ++i) { float angle = (float)i * M_PI / (float)CIRCLE_SEG_NUM * 2.0f; Point d(radius * cosf(angle), radius * sinf(angle)); seg[i] = centre + d; } _drawNode->drawPolygon(seg, CIRCLE_SEG_NUM, Color4F(1.0f, 0.0f, 0.0f, 0.3f), 1, Color4F(1, 0, 0, 1)); break; } case CP_SEGMENT_SHAPE: { cpSegmentShape *seg = (cpSegmentShape *)subShape; _drawNode->drawSegment(PhysicsHelper::cpv2point(seg->ta), PhysicsHelper::cpv2point(seg->tb), PhysicsHelper::cpfloat2float(seg->r==0 ? 1 : seg->r), Color4F(1, 0, 0, 1)); break; } case CP_POLY_SHAPE: { cpPolyShape* poly = (cpPolyShape*)subShape; int num = poly->numVerts; Point* seg = new Point[num]; PhysicsHelper::cpvs2points(poly->tVerts, seg, num); _drawNode->drawPolygon(seg, num, Color4F(1.0f, 0.0f, 0.0f, 0.3f), 1.0f, Color4F(1.0f, 0.0f, 0.0f, 1.0f)); delete[] seg; break; } default: break; } } }
void PhysicsShapeCircle::updateScale() { cpFloat factor = std::abs(_newScaleX / _scaleX); cpShape* shape = _cpShapes.front(); cpVect v = cpCircleShapeGetOffset(shape); v = cpvmult(v, factor); cpCircleShapeSetOffset(shape, v); cpCircleShapeSetRadius(shape, cpCircleShapeGetRadius(shape) * factor); PhysicsShape::updateScale(); }
void PhysicsShapeCircle::updateScale() { cpFloat factor = std::abs(PhysicsHelper::float2cpfloat(_newScaleX / _scaleX)); cpShape* shape = _cpShapes.front(); cpVect v = cpCircleShapeGetOffset(shape); v = cpvmult(v, PhysicsHelper::float2cpfloat(factor)); ((cpCircleShape*)shape)->c = v; cpCircleShapeSetRadius(shape, cpCircleShapeGetRadius(shape) * factor); PhysicsShape::updateScale(); }
/* calculate moment for a single shape */ static Scalar _moment(cpBody *body, ShapeInfo *shapeInfo) { Scalar mass = cpBodyGetMass(body); switch (shapeInfo->type) { case PS_CIRCLE: return cpMomentForCircle(mass, 0, cpCircleShapeGetRadius(shapeInfo->shape), cpCircleShapeGetOffset(shapeInfo->shape)); case PS_POLYGON: return cpMomentForPoly(mass, cpPolyShapeGetNumVerts(shapeInfo->shape), ((cpPolyShape *) shapeInfo->shape)->verts, cpvzero); } }
void draw_background(SDL_Surface* screen) { struct draw_options opts = { .surface = screen, .colour = colour(0, 0, 0) }; sdldraw_rect(opts, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } static void draw_circle_shape(struct draw_options opts, cpShape* shape, cpBody* body) { cpVect centre = cpvadd(cpBodyGetPos(body), cpCircleShapeGetOffset(shape)); cpFloat radius = cpCircleShapeGetRadius(shape); cpFloat angle = cpBodyGetAngle(body); cpVect edgePoint = cpvadd(centre, cpv(radius * cos(angle), radius * sin(angle))); draw_circle(opts, centre, radius); draw_line(opts, centre, edgePoint); }
float PhysicsShapeCircle::getRadius() const { return PhysicsHelper::cpfloat2float(cpCircleShapeGetRadius(_cpShapes.front())); }
float PhysicsShapeCircle::calculateArea() { return PhysicsHelper::cpfloat2float(cpAreaForCircle(0, cpCircleShapeGetRadius(_cpShapes.front()))); }
float radius() const { return cpCircleShapeGetRadius(_shape); }
float PhysicsShapeCircle::getRadius() { return PhysicsHelper::cpfloat2float(cpCircleShapeGetRadius(_info->shapes.front())); }
JNIEXPORT jfloat JNICALL Java_johang_chipmunk_CircleShape_getRadius( JNIEnv *env, jobject self) { cpShape *ptrShape = jgGetCpShapePtr(env, self); return cpCircleShapeGetRadius(ptrShape); }
void landerDraw(Lander l) { drawCircle(l->body->p, cpvtoangle(l->body->rot), cpCircleShapeGetRadius(l->shape), RGBAColor(1.0, 1.0, 1.0, 1.0), RGBAColor(0.0, 0.0, 0.0, 1.0)); }