Example #1
0
void RCPBody::applyImpulse(RVector const & impulse)
{
    if (mBody) {
        cpBodyApplyImpulseAtWorldPoint(mBody, cpv(impulse.x(), impulse.y()), cpBodyLocalToWorld(mBody, cpBodyGetCenterOfGravity(mBody)));
    }

}
Example #2
0
void Slice::ClipPoly(cpSpace *space, cpShape *shape, cpVect n, cpFloat dist)
{
	cpBody *body = cpShapeGetBody(shape);
	
	int count = cpPolyShapeGetCount(shape);
	int clippedCount = 0;
	
	cpVect *clipped = (cpVect *)alloca((count + 1)*sizeof(cpVect));
	
	for(int i=0, j=count-1; i<count; j=i, i++){
		cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(shape, j));
		cpFloat a_dist = cpvdot(a, n) - dist;
		
		if(a_dist < 0.0){
			clipped[clippedCount] = a;
			clippedCount++;
		}
		
		cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(shape, i));
		cpFloat b_dist = cpvdot(b, n) - dist;
		
		if(a_dist*b_dist < 0.0f){
			cpFloat t = cpfabs(a_dist)/(cpfabs(a_dist) + cpfabs(b_dist));
			
			clipped[clippedCount] = cpvlerp(a, b, t);
			clippedCount++;
		}
	}
	
	cpVect centroid = cpCentroidForPoly(clippedCount, clipped);
	cpFloat mass = cpAreaForPoly(clippedCount, clipped, 0.0f)*DENSITY;
	cpFloat moment = cpMomentForPoly(mass, clippedCount, clipped, cpvneg(centroid), 0.0f);
	
	cpBody *new_body = cpSpaceAddBody(space, cpBodyNew(mass, moment));
	cpBodySetPosition(new_body, centroid);
	cpBodySetVelocity(new_body, cpBodyGetVelocityAtWorldPoint(body, centroid));
	cpBodySetAngularVelocity(new_body, cpBodyGetAngularVelocity(body));
	
	cpTransform transform = cpTransformTranslate(cpvneg(centroid));
	cpShape *new_shape = cpSpaceAddShape(space, cpPolyShapeNew(new_body, clippedCount, clipped, transform, 0.0));
	// Copy whatever properties you have set on the original shape that are important
	cpShapeSetFriction(new_shape, cpShapeGetFriction(shape));
}
Example #3
0
	int applykeys(Ship* s, bool* keylist)
	{
		if (keylist[0])
			cpBodyApplyForceAtLocalPoint(s->body, cpv(0, 1e7), cpv(0.5, 0));
		if (keylist[1])
			cpBodyApplyForceAtLocalPoint(s->body, cpv(0, -1e6), cpv(0.5, 3));
		if (keylist[2])
		{
			cpBodyApplyForceAtLocalPoint(s->body, cpv(1e6, 0), cpv(0, 0));
			cpBodyApplyForceAtLocalPoint(s->body, cpv(-1e6, 0), cpv(1, 3));
		}
		if (keylist[3])
		{
			cpBodyApplyForceAtLocalPoint(s->body, cpv(1e6, 0), cpv(0, 3));
			cpBodyApplyForceAtLocalPoint(s->body, cpv(-1e6, 0), cpv(1, 0));
		}
		if (keylist[4])
		{
			cpBodyApplyForceAtLocalPoint(s->body, cpv(-1e6, 0), cpv(1, 3));
			cpBodyApplyForceAtLocalPoint(s->body, cpv(-1e6, 0), cpv(1, 0));
		}
		if (keylist[5])
		{
			cpBodyApplyForceAtLocalPoint(s->body, cpv(1e6, 0), cpv(0, 3));
			cpBodyApplyForceAtLocalPoint(s->body, cpv(1e6, 0), cpv(0, 0));
		}

		
		if (keylist[6] && last_time_updated - s->last_fired > 1)
		{			
			cpVect tip = cpBodyLocalToWorld(s->body, nosev + cpv(0, 0.1));
			cpVect base = cpBodyLocalToWorld(s->body, cpv(0.5, 0));
			
			cpVect newvel = cpvnormalize(tip - base) * shell_muzzle_vel + cpBodyGetVelocityAtLocalPoint(s->body, nosev);
			Shell* newshell = addshell(tip, newvel, cpBodyGetAngle(s->body));
			cpBodyApplyImpulseAtLocalPoint(s->body, cpv(0, -1)*cpBodyGetMass(newshell->body)*shell_muzzle_vel, cpv(0.5, 3));
			
			s->last_fired = last_time_updated;
		}
		
		
		return 0;
	}
Example #4
0
	Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
	{
		cpVect cog = cpBodyGetCenterOfGravity(m_handle);

		switch (coordSys)
		{
			case CoordSys_Global:
				cog = cpBodyLocalToWorld(m_handle, cog);
				break;

			case CoordSys_Local:
				break; // Nothing to do
		}

		return Vector2f(static_cast<float>(cog.x), static_cast<float>(cog.y));
	}
Example #5
0
Vec2 PhysicsBody::local2World(const Vec2& point)
{
    return PhysicsHelper::cpv2point(cpBodyLocalToWorld(_cpBody, PhysicsHelper::point2cpv(point)));
}
Example #6
0
struct gun instantiate_gun(struct obj *owner, const char *gunType,
                           const char *bulletType)
{
//    fprintf(stderr, "\n\n\n%s\n\n\n", bulletType);
    struct gun ret = {.bulletType = strdup(bulletType), .owner = owner, .cooldown = owner->room->ticks};
    ret.fire =  guntbl_find(&fires, gunType);
    return ret;
}

void machinegun_fire(struct gun *self)
{
    if (self->owner->room->ticks - self->cooldown > 1) {
        struct obj *bullet = instantiate_object(self->bulletType,
                                                self->owner->objectVect,
                                                self->owner->room);

        cpBodySetPosition(bullet->body,
                          cpBodyLocalToWorld(self->owner->body,
                                             cpv(0, -self->owner->radius - bullet->radius - 2)));

        cpBodySetMoment(bullet->body,
                        cpMomentForCircle(10000.0, 0.0,
                                          bullet->radius*2, cpvzero));
        cpBodySetAngle(bullet->body, cpBodyGetAngle(self->owner->body) + M_PI);
        ((struct bullet_extra*)bullet->extra)->speed = 20.0;
        ((struct bullet_extra*)bullet->extra)->owner = self->owner;

        cpBodyApplyImpulseAtLocalPoint(self->owner->body,
                                       cpv(0, 50.0),
                                       cpv(0, -(self->owner->radius * 2)));
        
        self->cooldown = self->owner->room->ticks;
    }
}
struct gunpair {
    const char *name;
    const gunmethod method;
};

void register_guns(void)
{
    struct gunpair pairs[] = {{"machine gun", machinegun_fire}};

    for (size_t i = 0; i < ARRAY_LENGTH(pairs); i++) {
        char *currentName = pairs[i].name;
        gunmethod currentMethod = pairs[i].method;

        if ((!currentName && currentMethod) || (currentName && !currentMethod)) {
            CROAK("Unevenly sized methodpair array");
        }
        guntbl_insert(&fires, currentName, currentMethod);
    }
}


void guntbl_insert(struct guntbl *table, const char *key, gunmethod method)
{
    int offset = hash(key) % 32;
    if (table->keys[offset]) {
		if (strcmp(table->keys[offset], key) == 0 ) {
			table->methods[offset] = method;
		} else {
			if (!table->next)
			{
				table->next = malloc(sizeof(struct guntbl));
				*table->next = (struct guntbl){.next = NULL};
			}
			guntbl_insert(table->next, key, method);
		} 
	} else {
Example #7
0
cpBool Buoyancy::WaterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr)
{
    CP_ARBITER_GET_SHAPES(arb, water, poly);
    cpBody *body = cpShapeGetBody(poly);

    // Get the top of the water sensor bounding box to use as the water level.
    cpFloat level = cpShapeGetBB(water).t;

    // Clip the polygon against the water level
    int count = cpPolyShapeGetCount(poly);
    int clippedCount = 0;
#ifdef _MSC_VER
    // MSVC is pretty much the only compiler in existence that doesn't support variable sized arrays.
    cpVect clipped[10];
#else
    cpVect clipped[count + 1];
#endif

    for(int i=0, j=count-1; i<count; j=i, i++){
        cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, j));
        cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, i));

        if(a.y < level){
            clipped[clippedCount] = a;
            clippedCount++;
        }

        cpFloat a_level = a.y - level;
        cpFloat b_level = b.y - level;

        if(a_level*b_level < 0.0f){
            cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level));

            clipped[clippedCount] = cpvlerp(a, b, t);
            clippedCount++;
        }
    }

    // Calculate buoyancy from the clipped polygon area
    cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped, 0.0f);
    cpFloat displacedMass = clippedArea*FLUID_DENSITY;
    cpVect centroid = cpCentroidForPoly(clippedCount, clipped);

    cpDataPointer data = ptr;
    DrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f), data);
    DrawDot(5, centroid, RGBAColor(0, 0, 1, 1), data);

    cpFloat dt = cpSpaceGetCurrentTimeStep(space);
    cpVect g = cpSpaceGetGravity(space);

    // Apply the buoyancy force as an impulse.
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(g, -displacedMass*dt), centroid);

    // Apply linear damping for the fluid drag.
    cpVect v_centroid = cpBodyGetVelocityAtWorldPoint(body, centroid);
    cpFloat k = k_scalar_body(body, centroid, cpvnormalize(v_centroid));
    cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY;
    cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag
    //	cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), centroid);

    // Apply angular damping for the fluid drag.
    cpVect cog = cpBodyLocalToWorld(body, cpBodyGetCenterOfGravity(body));
    cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(cog), 0.0f);
    cpBodySetAngularVelocity(body, cpBodyGetAngularVelocity(body)*cpfexp(-w_damping*dt/cpBodyGetMoment(body)));

    return cpTrue;
}