Ejemplo n.º 1
0
Line::Line(ShapeLine *src, float mass){
    cpFloat moment = cpMomentForSegment(mass, toChipmunk(src->getA()), toChipmunk(src->getB()), src->getRadius());
    DynamicBody::setup(cpShapeGetSpace(src->shape), mass, moment);
    ShapeLine::setup(src);
    cpSpaceRemoveShape(cpShapeGetSpace(shape), shape);
    cpSpaceAddShape(cpBodyGetSpace(body), shape);
    cpShapeSetBody(shape, body);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
static cpBody *utils_update_drawing(cpBody *drawing) {
    cpFloat mass = cpBodyGetMass(drawing);
    cpFloat moment = cpBodyGetMoment(drawing);
    
    Body_data *pa = cpBodyGetUserData(drawing);
    //cpFloat x = g_array_index(pa->x_values, cpFloat, 0);
    //cpFloat y = g_array_index(pa->y_values, cpFloat, 0);
    
    cpVect pos_a, pos_b;
    cpVect origin = cpBodyGetPos(drawing);
    
    cpFloat mi, micx = 0, micy = 0;
    int length = pa->x_values->len;
    for (int index = 1; index < length; index++) {
        pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1));
        pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index));
	 	//fprintf(stdout, "Pos_a = (%5.2f, %5.2f)\n", pos_a.x, pos_a.y);
		
        mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS ));
        micx += mi * ((pos_a.x + pos_b.x) / 2);
        micy += mi * ((pos_a.y + pos_b.y) / 2);
        
        mass += mi;
        moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum, but maybe it is
    }

    cpBodySetMass(drawing, mass);
    cpBodySetMoment(drawing, moment);
    
    // center of mass is the average of all vertices  NOT
    //cpVect new_origin = cpv(x / length, y / length);
    cpVect new_origin = cpv(micx / mass, micy / mass);
    new_origin = cpBodyLocal2World(drawing, new_origin);
    cpBodySetPos( drawing, new_origin );
	//fprintf(stdout, "Position set at (%5.2f, %5.2f)\n", new_origin.x, new_origin.y);
    cpSpace * space = cpBodyGetSpace(drawing);
	cpSpaceReindexShapesForBody(space, drawing);
    //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length)));
    //pa->offset = cpvsub(new_origin, origin);
    pa = shift_origin(drawing, origin, new_origin);
    cpBodySetUserData(drawing, pa);
	if (space)
		post_step_body_replace_shapes(space, drawing, NULL);
	else
		fprintf(stderr, "WTF\n");

	//if (!(cpSpaceAddPostStepCallback(space, (cpPostStepFunc) post_step_body_replace_shapes, drawing, NULL)))
		//fprintf(stderr, "FAILED POST-STEP CALLBACK\n\n");
	
    return drawing;
}
Ejemplo n.º 5
0
__declspec( dllexport ) void momentforsegment( const void * _in, int in_size, void * _out, int out_sz )
{
	cpVect translated1 = PEEKVECT(INPUT_MEMBLOCK,4);
	cpVect translated2 = PEEKVECT(INPUT_MEMBLOCK,12);
	cpVect offset = PEEKVECT(INPUT_MEMBLOCK,20);

	translated1.x += offset.x;
	translated1.y += offset.y;
		
	translated2.x += offset.x;
	translated2.y += offset.y;

	POKEFLOAT(OUTPUT_MEMBLOCK,0,cpMomentForSegment(PEEKFLOAT(INPUT_MEMBLOCK,0),translated1,translated2));
}
Ejemplo n.º 6
0
static cpBody *
addBar(cpVect pos, cpVect boxOffset)
{
	cpFloat mass = 2.0f;
	cpVect a = cpv(0,  30);
	cpVect b = cpv(0, -30);
	
	cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
	body->p = cpvadd(pos, boxOffset);
	
	cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 5.0f));
	shape->e = 0.0f; shape->u = 0.7f;
	
	return body;
}
Ejemplo n.º 7
0
static cpBody *
addBar(cpVect pos, cpVect boxOffset)
{
	cpFloat mass = 2.0f;
	cpVect a = cpv(0,  30);
	cpVect b = cpv(0, -30);
	
	cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
	cpBodySetPos(body, cpvadd(pos, boxOffset));
	
	cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 5.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.7f);
	
	return body;
}
Ejemplo n.º 8
0
static cpBody *utils_update_drawing(cpBody *drawing) {
    cpFloat mass = cpBodyGetMass(drawing);
    cpFloat moment = cpBodyGetMoment(drawing);
    
    Point_array *pa = cpBodyGetUserData(drawing);
    cpFloat x = g_array_index(pa->x_values, cpFloat, 0);
    cpFloat y = g_array_index(pa->y_values, cpFloat, 0);
    
    cpVect pos_a, pos_b;
    cpVect origin = cpBodyGetPos(drawing);
    
    cpFloat mi, micx = 0, micy = 0;
    int length = pa->x_values->len;
    for (int index = 1; index < length; index++) {
        pos_a = cpv(g_array_index(pa->x_values, cpFloat, index - 1), g_array_index(pa->y_values, cpFloat, index - 1));
        pos_b = cpv(g_array_index(pa->x_values, cpFloat, index), g_array_index(pa->y_values, cpFloat, index));
 	cpvadd(pos_a, origin);
	cpvadd(pos_b, origin);       
        x += pos_b.x;
        y += pos_b.y;
        
        mi = (CRAYON_MASS * cpAreaForSegment( pos_a, pos_b, CRAYON_RADIUS ));
        micx += mi * ((pos_a.x + pos_b.x) / 2);
        micy += mi * ((pos_a.y + pos_b.y) / 2);
        
        mass += mi;
        moment += cpMomentForSegment(mass, pos_a, pos_b); // not actually sum
    }

    cpBodySetMass(drawing, mass);
    cpBodySetMoment(drawing, moment);
    
    // center of mass is the average of all vertices  NOT
    //cpVect new_origin = cpv(x / length, y / length);
    cpVect new_origin = cpv(micx / mass, micy / mass);
    cpBodySetPos( drawing, new_origin );
    //cpBodySetPos(drawing, cpv(pos.x + (second.x / length), pos.y + (second.y / length)));
    
    pa = shift_origin(pa, origin, new_origin);
    cpBodySetUserData(drawing, pa);
    
    return drawing;
}
Ejemplo n.º 9
0
cpFloat
cpMomentForPoly(cpFloat m, const int numVerts, const cpVect *verts, cpVect offset)
{
	if(numVerts == 2) return cpMomentForSegment(m, verts[0], verts[1]);
	
	cpFloat sum1 = 0.0f;
	cpFloat sum2 = 0.0f;
	for(int i=0; i<numVerts; i++){
		cpVect v1 = cpvadd(verts[i], offset);
		cpVect v2 = cpvadd(verts[(i+1)%numVerts], offset);
		
		cpFloat a = cpvcross(v2, v1);
		cpFloat b = cpvdot(v1, v1) + cpvdot(v1, v2) + cpvdot(v2, v2);
		
		sum1 += a*b;
		sum2 += a;
	}
	
	return (m*sum1)/(6.0f*sum2);
}
Ejemplo n.º 10
0
cpFloat
cpMomentForPoly(cpFloat m, const int count, const cpVect *verts, cpVect offset, cpFloat radius)
{
	if(count == 2) return cpMomentForSegment(m, verts[0], verts[1], radius);
	
	cpFloat sum1 = 0.0f;
	cpFloat sum2 = 0.0f;
	for(int i=0; i<count; i++){
		cpVect v1 = cpvadd(verts[i], offset);
		cpVect v2 = cpvadd(verts[(i+1)%count], offset);
		
		cpFloat a = cpvcross(v2, v1);
		cpFloat b = cpvdot(v1, v1) + cpvdot(v1, v2) + cpvdot(v2, v2);
		
		sum1 += a*b;
		sum2 += a;
	}
	
	// TODO account for radius.
	return (m*sum1)/(6.0f*sum2);
}
Ejemplo n.º 11
0
Mirror::Mirror(ResourceManager& a_ResMgr, cpSpace& a_Space)
:	GameObject(a_ResMgr, a_Space)
{
	//create le sprite
	m_resMgr.CreateSprite("media/mirror2.png", &m_Sprite);
	m_resMgr.AddDrawableSprite(&m_Sprite);
	sf::Vector2u sprSize = m_Sprite.sprite->getTexture()->getSize();
	m_Sprite.sprite->setOrigin(sprSize.x/2,sprSize.y/2);
	
	//moment of inertia (rotation thing)
	cpFloat length = m_Sprite.sprite->getTexture()->getSize().x;
	cpFloat mass = 1;
	cpFloat moment = cpMomentForSegment(mass, cpv(0,0), cpv(0,length));

	//---------------top
	//create physbody
	m_pReflectBody = cpSpaceAddBody(&a_Space, cpBodyNew(mass, moment));
	m_pReflectBody->data = this;
	//create collision line
	m_pReflectLine = cpSpaceAddShape( &a_Space, cpSegmentShapeNew(m_pReflectBody, cpv(0,0), cpv(sprSize.x,0), 1) );
	cpShapeSetFriction(m_pReflectLine, 0);
	m_pReflectLine->data = this;
	m_pReflectLine->sensor = 1;
	
	//only have the reflect line call the callbacks
	cpShapeSetCollisionType(m_pReflectLine, MIRROR);

	//---------------bottom
	//create physbody
	m_pBody = cpSpaceAddBody(&a_Space, cpBodyNew(mass, moment));
	m_pBody->data = this;
	//create collision line
	m_pShape = cpSpaceAddShape( &a_Space, cpSegmentShapeNew(m_pBody, cpv(0,sprSize.y), cpv(sprSize.x,sprSize.y), 1) );
	cpShapeSetFriction(m_pShape, 0);
	m_pShape->data = this;
}
Ejemplo n.º 12
0
static VALUE
rb_cpMomentForSegment(VALUE self, VALUE m, VALUE v1, VALUE v2) {
  cpFloat i = cpMomentForSegment(NUM2DBL(m), *VGET(v1), *VGET(v2));
  return rb_float_new(i);
}
Ejemplo n.º 13
0
static cpSpace *
init(void)
{
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	space->elasticIterations = 0;
	space->iterations = 5;

	cpSpaceResizeStaticHash(space, 40.0f, 999);
	cpSpaceResizeActiveHash(space, 30.0f, 2999);

	cpBody *staticBody = &space->staticBody;
	cpShape *shape;
	
	// add a non-collidable segment as a quick and dirty way to draw the query line
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpvzero, cpv(100.0f, 0.0f), 4.0f));
	shape->layers = 0;
	querySeg = shape;
	
	{ // 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)));
		body->p = cpv(0.0f, 100.0f);
		
		cpSpaceAddShape(space, cpSegmentShapeNew(body, a, b, 20.0f));
	}
	
	{ // add a static segment
		cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, 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*(cpFloat)M_PI*i/((cpFloat) NUM_VERTS);
			verts[i] = cpv(30*cosf(angle), 30*sinf(angle));
		}
		
		cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, NUM_VERTS, verts, cpvzero)));
		body->p = 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)));
		body->p = cpv(100.0f, 100.0f);
		
		cpSpaceAddShape(space, cpCircleShapeNew(body, r, cpvzero));
	}
	
	return space;
}
Ejemplo n.º 14
0
static cpSpace *
init(void)
{
	ChipmunkDemoMessageString = "Use the arrow keys to control the machine.";
	
	space = cpSpaceNew();
	cpSpaceSetGravity(space, cpv(0, -600));
	
	cpBody *staticBody = cpSpaceGetStaticBody(space);
	cpShape *shape;
	
	// beveling all of the line segments slightly helps prevent things from getting stuck on cracks
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-256,300), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-192,0), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,0), cpv(-192, -64), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,-64), cpv(-128,144), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,80), cpv(-192,176), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,176), cpv(-128,240), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,144), cpv(192,64), 2.0f));
	cpShapeSetElasticity(shape, 0.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, NOT_GRABABLE_MASK);

	cpVect verts[] = {
		cpv(-30,-80),
		cpv(-30, 80),
		cpv( 30, 64),
		cpv( 30,-80),
	};

	cpBody *plunger = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
	cpBodySetPos(plunger, cpv(-160,-80));
	
	shape = cpSpaceAddShape(space, cpPolyShapeNew(plunger, 4, verts, cpvzero));
	cpShapeSetElasticity(shape, 1.0f);
	cpShapeSetFriction(shape, 0.5f);
	cpShapeSetLayers(shape, 1);
	
	// add balls to hopper
	for(int i=0; i<numBalls; i++)
		balls[i] = add_ball(cpv(-224 + i,80 + 64*i));
	
	// add small gear
	cpBody *smallGear = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 80, 0, cpvzero)));
	cpBodySetPos(smallGear, cpv(-160,-160));
	cpBodySetAngle(smallGear, -M_PI_2);

	shape = cpSpaceAddShape(space, cpCircleShapeNew(smallGear, 80.0f, cpvzero));
	cpShapeSetLayers(shape, 0);
	
	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, smallGear, cpv(-160,-160), cpvzero));

	// add big gear
	cpBody *bigGear = cpSpaceAddBody(space, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 160, 0, cpvzero)));
	cpBodySetPos(bigGear, cpv(80,-160));
	cpBodySetAngle(bigGear, M_PI_2);
	
	shape = cpSpaceAddShape(space, cpCircleShapeNew(bigGear, 160.0f, cpvzero));
	cpShapeSetLayers(shape, 0);
	
	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, bigGear, cpv(80,-160), cpvzero));

	// connect the plunger to the small gear.
	cpSpaceAddConstraint(space, cpPinJointNew(smallGear, plunger, cpv(80,0), cpv(0,0)));
	// connect the gears.
	cpSpaceAddConstraint(space, cpGearJointNew(smallGear, bigGear, -M_PI_2, -2.0f));
	
	
	// feeder mechanism
	cpFloat bottom = -300.0f;
	cpFloat top = 32.0f;
	cpBody *feeder = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForSegment(1.0f, cpv(-224.0f, bottom), cpv(-224.0f, top))));
	cpBodySetPos(feeder, cpv(-224, (bottom + top)/2.0f));
	
	cpFloat len = top - bottom;
	cpSpaceAddShape(space, cpSegmentShapeNew(feeder, cpv(0.0f, len/2.0f), cpv(0.0f, -len/2.0f), 20.0f));
	
	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, feeder, cpv(-224.0f, bottom), cpv(0.0f, -len/2.0f)));
	cpVect anchr = cpBodyWorld2Local(feeder, cpv(-224.0f, -160.0f));
	cpSpaceAddConstraint(space, cpPinJointNew(feeder, smallGear, anchr, cpv(0.0f, 80.0f)));

	// motorize the second gear
	motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(staticBody, bigGear, 3.0f));

	return space;
}
Ejemplo n.º 15
0
static VALUE
rb_momentForSegment(VALUE self, VALUE m, VALUE a, VALUE b)
{
    cpFloat i = cpMomentForSegment(NUM2DBL(m), *VGET(a), *VGET(b));
    return rb_float_new(i);
}
Ejemplo n.º 16
0
Archivo: physics.c Proyecto: dns/CLove
/*
 * The moment is like the rotational mass of a body
 * Note: !This function may also set the mass of the object!
 */
static int l_physics_setBodyMoment(lua_State* state)
{
    l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body");
    l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1);

    /*
     * You can provide a custom moment
     * for this body *or* you can choose what
     * type of body this is and let chipmunk
     * calculate the value based on some attributes
     */

    int index = 2;

    cpFloat _mass = 0;
    cpFloat moment = 0;
    if (lua_type(state, 2) == LUA_TNUMBER)
    {
        moment = l_tools_toNumberOrError(state, 2);
    }
    else if (lua_type(state, 2) == LUA_TSTRING)
    {
        const char* whatFor = lua_tostring(state, 2);
        if (strcmp(whatFor, "box") == 0)
        {
            cpFloat mass = l_tools_toNumberOrError(state, 3);
            cpFloat width = l_tools_toNumberOrError(state, 4);
            cpFloat height = l_tools_toNumberOrError(state, 5);
            _mass = mass;
            moment = cpMomentForBox(mass, width, height);
        }
        else if (strcmp(whatFor, "circle") == 0)
        {
            cpFloat mass = l_tools_toNumberOrError(state, index++);
            cpFloat inner_radius = l_tools_toNumberOrError(state, index++);
            cpFloat outer_radius = l_tools_toNumberOrError(state, index++);
            cpVect offset = cpvzero;
            offset.x = l_tools_toNumberOrError(state, index++);
            offset.y = l_tools_toNumberOrError(state, index++);
            _mass = mass;
            moment = cpMomentForCircle(mass, inner_radius, outer_radius, offset);
        }
        else if (strcmp(whatFor, "segment") == 0)
        {

            cpFloat mass = l_tools_toNumberOrError(state, index++);

            cpVect a = cpvzero;
            a.x = l_tools_toNumberOrError(state, index++);
            a.y = l_tools_toNumberOrError(state, index++);
            cpVect b = cpvzero;
            b.x = l_tools_toNumberOrError(state, index++);
            b.y = l_tools_toNumberOrError(state, index++);

            cpFloat radius = l_tools_toNumberOrError(state, index++);
            _mass = mass;
            moment = cpMomentForSegment(mass, a, b, radius);
        }
    }

    if (_mass > 0)
        cpBodySetMass(body->body, _mass);

    cpBodySetMoment(body->body, moment);

    return 0;
}
Ejemplo n.º 17
0
static cpSpace *
init(void)
{
	space = cpSpaceNew();
	space->gravity = cpv(0, -600);

	cpBody *staticBody = &space->staticBody;
	cpShape *shape;

	// beveling all of the line segments slightly helps prevent things from getting stuck on cracks
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-256,300), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-192,0), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,0), cpv(-192, -64), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,-64), cpv(-128,144), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,80), cpv(-192,176), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,176), cpv(-128,240), 2.0f));
	shape->e = 0.0f; shape->u = 0.0f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,144), cpv(192,64), 2.0f));
	shape->e = 0.0f; shape->u = 0.5f; shape->layers = 1;
	shape->layers = NOT_GRABABLE_MASK;

	cpVect verts[] = {
		cpv(-30,-80),
		cpv(-30, 80),
		cpv( 30, 64),
		cpv( 30,-80),
	};

	cpBody *plunger = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY));
	plunger->p = cpv(-160,-80);

	shape = cpSpaceAddShape(space, cpPolyShapeNew(plunger, 4, verts, cpvzero));
	shape->e = 1.0f; shape->u = 0.5f; shape->layers = 1;

	// add balls to hopper
	for(int i=0; i<numBalls; i++)
		balls[i] = add_ball(cpv(-224 + i,80 + 64*i));

	// add small gear
	cpBody *smallGear = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 80, 0, cpvzero)));
	smallGear->p = cpv(-160,-160);
	cpBodySetAngle(smallGear, (cpFloat)-M_PI_2);

	shape = cpSpaceAddShape(space, cpCircleShapeNew(smallGear, 80.0f, cpvzero));
	shape->layers = 0;

	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, smallGear, cpv(-160,-160), cpvzero));

	// add big gear
	cpBody *bigGear = cpSpaceAddBody(space, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 160, 0, cpvzero)));
	bigGear->p = cpv(80,-160);
	cpBodySetAngle(bigGear, (cpFloat)M_PI_2);

	shape = cpSpaceAddShape(space, cpCircleShapeNew(bigGear, 160.0f, cpvzero));
	shape->layers = 0;

	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, bigGear, cpv(80,-160), cpvzero));

	// connect the plunger to the small gear.
	cpSpaceAddConstraint(space, cpPinJointNew(smallGear, plunger, cpv(80,0), cpv(0,0)));
	// connect the gears.
	cpSpaceAddConstraint(space, cpGearJointNew(smallGear, bigGear, (cpFloat)-M_PI_2, -2.0f));


	// feeder mechanism
	cpFloat bottom = -300.0f;
	cpFloat top = 32.0f;
	cpBody *feeder = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForSegment(1.0f, cpv(-224.0f, bottom), cpv(-224.0f, top))));
	feeder->p = cpv(-224, (bottom + top)/2.0f);

	cpFloat len = top - bottom;
	cpSpaceAddShape(space, cpSegmentShapeNew(feeder, cpv(0.0f, len/2.0f), cpv(0.0f, -len/2.0f), 20.0f));

	cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, feeder, cpv(-224.0f, bottom), cpv(0.0f, -len/2.0f)));
	cpVect anchr = cpBodyWorld2Local(feeder, cpv(-224.0f, -160.0f));
	cpSpaceAddConstraint(space, cpPinJointNew(feeder, smallGear, anchr, cpv(0.0f, 80.0f)));

	// motorize the second gear
	motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(staticBody, bigGear, 3.0f));

	return space;
}
Ejemplo n.º 18
0
void Line::setup(cpSpace* space, glm::vec2 a, glm::vec2 b, float radius, float mass){
	DynamicBody::setup(space, mass, cpMomentForSegment(mass, toChipmunk(a), toChipmunk(b), radius));
    ShapeLine::setup(space, body, a, b, radius);
}
Ejemplo n.º 19
0
static cpSpace *
init(void)
{
	ChipmunkDemoMessageString = "Use the arrow keys to control the machine.";
	
	cpSpace *space = cpSpaceNew();
	cpSpaceSetIterations(space, 20);
	cpSpaceSetGravity(space, cpv(0,-500));
	
	cpBody *staticBody = cpSpaceGetStaticBody(space);
	cpShape *shape;
	cpVect a, b;
	
	// 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);
	
	cpFloat offset = 30.0f;

	// make chassis
	cpFloat chassis_mass = 2.0f;
	a = cpv(-offset, 0.0f), b = cpv(offset, 0.0f);
	cpBody *chassis = cpSpaceAddBody(space, cpBodyNew(chassis_mass, cpMomentForSegment(chassis_mass, a, b, 0.0f)));
	
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(chassis, a, b, seg_radius));
	cpShapeSetFilter(shape, cpShapeFilterNew(1, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES));
	
	// make crank
	cpFloat crank_mass = 1.0f;
	cpFloat crank_radius = 13.0f;
	cpBody *crank = cpSpaceAddBody(space, cpBodyNew(crank_mass, cpMomentForCircle(crank_mass, crank_radius, 0.0f, cpvzero)));
	
	shape = cpSpaceAddShape(space, cpCircleShapeNew(crank, crank_radius, cpvzero));
	cpShapeSetFilter(shape, cpShapeFilterNew(1, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES));
	
	cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, crank, cpvzero, cpvzero));
	
	cpFloat side = 30.0f;
	
	int num_legs = 2;
	for(int i=0; i<num_legs; i++){
		make_leg(space, side,  offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+0)/(cpFloat)num_legs*M_PI), crank_radius));
		make_leg(space, side, -offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+1)/(cpFloat)num_legs*M_PI), crank_radius));
	}
	
	motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(chassis, crank, 6.0f));

	return space;
}
Ejemplo n.º 20
0
GLMFloat world_momentForSegment(GLMFloat aMass, vec2_t a, vec2_t b)
{
    return cpMomentForSegment(aMass, VEC2_TO_CPV(a), VEC2_TO_CPV(b));
}