static unsigned int _shape_add(Entity ent, PhysicsShape type, cpShape *shape) { PhysicsInfo *info; ShapeInfo *shapeInfo; info = entitypool_get(pool, ent); error_assert(info); /* init ShapeInfo */ shapeInfo = array_add(info->shapes); shapeInfo->type = type; shapeInfo->shape = shape; /* init cpShape */ cpShapeSetBody(shape, info->body); cpSpaceAddShape(space, shape); cpShapeSetFriction(shapeInfo->shape, 1); cpShapeSetUserData(shapeInfo->shape, ent); /* update moment */ if (!cpBodyIsStatic(info->body)) { if (array_length(info->shapes) > 1) cpBodySetMoment(info->body, _moment(info->body, shapeInfo) + cpBodyGetMoment(info->body)); else cpBodySetMoment(info->body, _moment(info->body, shapeInfo)); } return array_length(info->shapes) - 1; }
bool PhysicsShapeBox::init(const Size& size, const PhysicsMaterial& material/* = MaterialDefault*/, const Vec2& offset /*= Vec2(0, 0)*/, float radius/* = 0.0f*/) { do { _type = Type::BOX; auto wh = PhysicsHelper::size2cpv(size); cpVect vec[4] = { {-wh.x/2.0f, -wh.y/2.0f}, {-wh.x/2.0f, wh.y/2.0f}, {wh.x/2.0f, wh.y/2.0f}, {wh.x/2.0f, -wh.y/2.0f} }; cpTransform transform = cpTransformTranslate(PhysicsHelper::point2cpv(offset)); auto shape = cpPolyShapeNew(s_sharedBody, 4, vec, transform, radius); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); addShape(shape); _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); setMaterial(material); return true; } while (false); return false; }
int mkparticle(particle_kind_t kind, cpVect pos, cpVect impulse, double energy) { particle_t* p = malloc(sizeof *p); if(p == NULL) { return -1; // bad malloc } cpSpace* space = current_space(); cpBody* body = cpBodyNew(energy / 1000.0, particle_moi); cpShape* shape = cpCircleShapeNew(body, particle_r, cpvzero); cpBodySetUserData(body, p); cpShapeSetUserData(shape, p); cpSpaceAddBody(space, body); cpSpaceAddShape(space, shape); *p = (particle_t){ .id = id, .kind = kind, .energy = energy, .life = energy, .body = body }; HASH_ADD_INT(particles, id, p); return id++; }
RigidBody2D& RigidBody2D::operator=(RigidBody2D&& object) { Destroy(); OnRigidBody2DMove = std::move(object.OnRigidBody2DMove); OnRigidBody2DRelease = std::move(object.OnRigidBody2DRelease); m_handle = object.m_handle; m_isStatic = object.m_isStatic; m_geom = std::move(object.m_geom); m_gravityFactor = object.m_gravityFactor; m_mass = object.m_mass; m_shapes = std::move(object.m_shapes); m_userData = object.m_userData; m_world = object.m_world; cpBodySetUserData(m_handle, this); for (cpShape* shape : m_shapes) cpShapeSetUserData(shape, this); object.m_handle = nullptr; OnRigidBody2DMove(&object, this); return *this; }
bool PhysicsShapePolygon::init(const Vec2* points, int count, const PhysicsMaterial& material/* = MaterialDefault*/, const Vec2& offset/* = Vec2(0, 0)*/, float radius/* = 0.0f*/) { do { _type = Type::POLYGEN; auto vecs = new (std::nothrow) cpVect[count]; PhysicsHelper::points2cpvs(points, vecs, count); //count = cpConvexHull((int)count, vecs, nullptr, nullptr, 0); cpTransform transform = cpTransformTranslate(PhysicsHelper::point2cpv(offset)); auto shape = cpPolyShapeNew(s_sharedBody, count, vecs, transform, radius); CC_SAFE_DELETE_ARRAY(vecs); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); addShape(shape); _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); 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; }
Shell(cpVect pos, cpVect vel, float angle) { cpVect vl[4] = {cpv(0, 0), cpv(0.1, 0), cpv(0.07, 0.3), cpv(0.03, 0.3)}; int vn = sizeof(vl)/sizeof(cpVect); float mass = cpAreaForPoly(vn, vl, 0) * shell_density; float moi = cpMomentForPoly(mass, vn, vl, cpv(0, 0), 0); body = cpBodyNew(mass, moi); cpshape = cpPolyShapeNew(body, vn, vl, cpTransformIdentity, 0); cpShapeSetFriction(cpshape, 0.9); cpVect centroid = cpCentroidForPoly(vn, vl); shape.setPointCount(vn); for (int i = 0; i < vn; i++) { shape.setPoint(i, sf::Vector2f(vl[i].x, vl[i].y)); } cpBodySetCenterOfGravity(body, centroid); cpBodySetPosition(body, pos-centroid); cpBodySetVelocity(body, vel); cpBodySetAngle(body, angle); cpShapeSetCollisionType(cpshape, 2); cpShapeSetUserData(cpshape, this); }
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; }
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; }
void PhysicsShape::addShape(cpShape* shape) { if (shape) { cpShapeSetUserData(shape, this); cpShapeSetFilter(shape, cpShapeFilterNew(_group, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES)); _cpShapes.push_back(shape); } }
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; }
void fff::kitty::Configure(){ fff::SetOriginByLua(game.vm, sprite, "kitty"); fff::SetOriginByLua(game.vm, flames[0], "flames"); flames[1].SetOrigin( flames[0].GetOrigin() ); flames[0].SetTexture(*game.textures["flames"]); flames[1].SetTexture(*game.textures["flames"]); flames[1].FlipX(true); burst.SetBuffer(*game.soundbuffers["burstinflames"]); shape = cpCircleShapeNew(body, fff::GetRadiusByLua(game.vm, "kitty"), (cpVect){0.f, 0.f} ); cpShapeSetUserData(shape, this); cpShapeSetCollisionType(shape, fff::collisions::types::kitty); }
Ship(int vn, cpVect* vl, cpVect pos, Genome* ng = 0) { float mass = cpAreaForPoly(vn, vl, 0) * ship_density; float moi = cpMomentForPoly(mass, vn, vl, cpv(0, 0), 0); body = cpBodyNew(mass, moi); cpshape = cpPolyShapeNew(body, vn, vl, cpTransformIdentity, 0); cpShapeSetFriction(cpshape, 0.9); cpVect centroid = cpCentroidForPoly(vn, vl); shape.setPointCount(vn); for (int i = 0; i < vn; i++) { shape.setPoint(i, sf::Vector2f(vl[i].x, vl[i].y)); } cpBodySetCenterOfGravity(body, centroid); cpBodySetPosition(body, pos-centroid); cpBodySetVelocity(body, cpv(0, 0)); cpShapeSetCollisionType(cpshape, 1); cpShapeSetUserData(cpshape, this); last_fired = 0; nose_angle = PI/2; player = false; target = 0; score = 0; if (ng == 0) { Genome* braingenome = mutate(readgenome("shipmind.mind")); brain = braingenome->makenetwork(); delete braingenome; } else { brain = ng->makenetwork(); } score = 0; }
RigidBody2D::RigidBody2D(RigidBody2D&& object) : OnRigidBody2DMove(std::move(object.OnRigidBody2DMove)), OnRigidBody2DRelease(std::move(object.OnRigidBody2DRelease)), m_shapes(std::move(object.m_shapes)), m_geom(std::move(object.m_geom)), m_userData(object.m_userData), m_handle(object.m_handle), m_world(object.m_world), m_isStatic(object.m_isStatic), m_gravityFactor(object.m_gravityFactor), m_mass(object.m_mass) { cpBodySetUserData(m_handle, this); for (cpShape* shape : m_shapes) cpShapeSetUserData(shape, this); object.m_handle = nullptr; OnRigidBody2DMove(&object, this); }
bool PhysicsShapeCircle::init(float radius, const PhysicsMaterial& material/* = MaterialDefault*/, const Vec2& offset /*= Vec2(0, 0)*/) { do { _type = Type::CIRCLE; auto shape = cpCircleShapeNew(s_sharedBody, radius, PhysicsHelper::point2cpv(offset)); CC_BREAK_IF(shape == nullptr); cpShapeSetUserData(shape, this); addShape(shape); _area = calculateArea(); _mass = material.density == PHYSICS_INFINITY ? PHYSICS_INFINITY : material.density * _area; _moment = calculateDefaultMoment(); setMaterial(material); return true; } while (false); return false; }
DynamicObject::DynamicObject(float x, float y, float scale, float mass, float elast, float fric, int type, std::string gpuPath, std::string vPath, std::string fPath) { gpuDataList.push_back(gpuStore.add(gpuPath, 3.1415f)); shaderList.push_back(shaderStore.add(vPath, fPath)); transformOverrides = false; height = scale; modelScale = glm::vec3(scale); width = height*gpuDataList[0]->whRatio; /*** Set physics data ***/ body = cpBodyNew(mass, 0); cpSpaceAddBody(space, body); cpBodySetPosition(body, cpv(x, y)); ObjGPUData* gpuData = gpuDataList[0]; int vertCount = gpuData->vList.size(); cpVect vertices[vertCount]; glm::vec3 pos(x, y, 0); for(int i = 0; i < vertCount; i++) { glm::vec4 currentVert = glm::translate(glm::mat4(1.0f), pos) * glm::scale(glm::mat4(1.0f), modelScale) * gpuData->rotation * gpuData->unitScale * glm::vec4(gpuData->vList[i],0); vertices[i] = cpv(currentVert.x, currentVert.y); } shape = cpSpaceAddShape(space, (cpShape*) cpPolyShapeInitRaw(cpPolyShapeAlloc(), body, vertCount, vertices, 1.0f)); cpBodySetMoment(body, abs(cpMomentForPoly(mass, vertCount, vertices, cpvzero, 1.0f))); cpShapeSetElasticity(shape, elast); cpShapeSetFriction(shape, fric); cpShapeSetUserData(shape, this); cpShapeSetCollisionType(shape, type); draw = true; }
void RigidBody2D::SetGeom(Collider2DRef geom, bool recomputeMoment) { // We have no public way of getting rid of an existing geom without removing the whole body // So let's save some attributes of the body, destroy it and rebuild it if (m_geom) { cpFloat mass = cpBodyGetMass(m_handle); cpFloat moment = cpBodyGetMoment(m_handle); cpBody* newHandle = Create(static_cast<float>(mass), static_cast<float>(moment)); CopyBodyData(m_handle, newHandle); Destroy(); m_handle = newHandle; } if (geom) m_geom = geom; else m_geom = NullCollider2D::New(); m_geom->GenerateShapes(this, &m_shapes); cpSpace* space = m_world->GetHandle(); for (cpShape* shape : m_shapes) cpShapeSetUserData(shape, this); if (m_isSimulationEnabled) RegisterToSpace(); if (recomputeMoment) { if (!IsStatic() && !IsKinematic()) cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass)); } }
void fff::explosive::prepareShape(cpSpace *space){ shape = cpCircleShapeNew( cpSpaceGetStaticBody(space), 1.f, (cpVect){0.f, 0.f} ); cpShapeSetUserData(shape, this); cpShapeSetCollisionType(shape, fff::collisions::types::explosive); cpShapeSetSensor(shape, cpTrue); }