Esempio n. 1
0
cpBody*
cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
{
	body->velocity_func = cpBodyUpdateVelocity;
	body->position_func = cpBodyUpdatePosition;
	
	cpBodySetMass(body, m);
	cpBodySetMoment(body, i);

	body->p = cpvzero;
	body->v = cpvzero;
	body->f = cpvzero;
	
	cpBodySetAngle(body, 0.0f);
	body->w = 0.0f;
	body->t = 0.0f;
	
	body->v_bias = cpvzero;
	body->w_bias = 0.0f;
	
	body->data = NULL;
//	body->active = 1;

	return body;
}
Esempio n. 2
0
void PhysicsBody::setMass(float mass)
{
    if (mass <= 0)
    {
        return;
    }
    
    _mass = mass;
    _massDefault = false;
    
    // update density
    if (_mass == PHYSICS_INFINITY)
    {
        _density = PHYSICS_INFINITY;
    }
    else
    {
        if (_area > 0)
        {
            _density = _mass / _area;
        }else
        {
            _density = 0;
        }
    }
    
    // the static body's mass and moment is always infinity
    if (_dynamic)
    {
        cpBodySetMass(_info->getBody(), PhysicsHelper::float2cpfloat(_mass));
    }
}
Esempio n. 3
0
cpBody*
cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
{
    body->velocity_func = cpBodyUpdateVelocityDefault;
    body->position_func = cpBodyUpdatePositionDefault;

    cpBodySetMass(body, m);
    cpBodySetMoment(body, i);

    body->p = cpvzero;
    body->v = cpvzero;
    body->f = cpvzero;

    cpBodySetAngle(body, 0.0f);
    body->w = 0.0f;
    body->t = 0.0f;

    body->v_bias = cpvzero;
    body->w_bias = 0.0f;

    body->data = NULL;
    body->v_limit = (cpFloat)INFINITY;
    body->w_limit = (cpFloat)INFINITY;

    body->space = NULL;
    body->shapesList = NULL;

    cpComponentNode node = {NULL, NULL, 0, 0.0f};
    body->node = node;

    return body;
}
Esempio n. 4
0
File: physics.c Progetto: dns/CLove
static int l_physics_setBodyMass(lua_State* state)
{
    l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body");
    l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1);

    float value = l_tools_toNumberOrError(state, 2);

    cpBodySetMass(body->body, value);

    return 0;
}
Esempio n. 5
0
void physics_set_mass(Entity ent, Scalar mass)
{
    PhysicsInfo *info = entitypool_get(pool, ent);
    error_assert(info);

    if (mass <= SCALAR_EPSILON)
        return;

    cpBodySetMass(info->body, info->mass = mass);
    _recalculate_moment(info);
}
Esempio n. 6
0
void PhysicsBody::setDynamic(bool dynamic)
{
    if (dynamic != _dynamic)
    {
        _dynamic = dynamic;
        if (dynamic)
        {
            cpBodySetMass(_info->getBody(), _mass);
            cpBodySetMoment(_info->getBody(), _moment);
            
            if (_world != nullptr)
            {
                // reset the gravity enable
                if (isGravityEnabled())
                {
                    _gravityEnabled = false;
                    setGravityEnable(true);
                }
                
                cpSpaceAddBody(_world->_info->getSpace(), _info->getBody());
            }
        }
        else
        {
            if (_world != nullptr)
            {
                cpSpaceRemoveBody(_world->_info->getSpace(), _info->getBody());
            }
            
            // avoid incorrect collion simulation.
            cpBodySetMass(_info->getBody(), PHYSICS_INFINITY);
            cpBodySetMoment(_info->getBody(), PHYSICS_INFINITY);
            cpBodySetVel(_info->getBody(), cpvzero);
            cpBodySetAngVel(_info->getBody(), 0.0f);
            resetForces();
        }
        
    }
}
Esempio n. 7
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;
}
Esempio n. 8
0
void PhysicsBody::updateMass(float oldMass, float newMass)
{
    if (_dynamic && !_gravityEnabled && _world != nullptr && oldMass != PHYSICS_INFINITY)
    {
        applyForce(_world->getGravity() * oldMass);
    }
    
    cpBodySetMass(_info->getBody(), newMass);
    
    if (_dynamic && !_gravityEnabled && _world != nullptr && newMass != PHYSICS_INFINITY)
    {
        applyForce(-_world->getGravity() * newMass);
    }
}
Esempio n. 9
0
void weapon_init(Entity *ent) {
    if (!weapon_sprite) {
        ALLEGRO_PATH *path = game_asset_path("sword.png");
        weapon_sprite = al_load_bitmap(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
        al_destroy_path(path);
    }
    cpBody *body = entity_body(ent);

    cpShape *shape = cpBoxShapeNew(body, WEAPON_WIDTH, WEAPON_HEIGHT, 0);
    cpSpaceAddShape(game.space, shape);
    cpShapeSetFriction(shape, 1);
    cpShapeSetElasticity(shape, 0);

    cpBodySetMass(body, 1);
    cpBodySetMoment(body, cpMomentForBox(1, WEAPON_WIDTH, WEAPON_HEIGHT));
}
Esempio n. 10
0
void PhysicsBody::addMass(float mass)
{
    if (mass == PHYSICS_INFINITY)
    {
        _mass = PHYSICS_INFINITY;
        _massDefault = false;
        _density = PHYSICS_INFINITY;
    }
    else if (mass == -PHYSICS_INFINITY)
    {
        return;
    }
    else
    {
        if (_massDefault)
        {
            _mass = 0;
            _massDefault = false;
        }

        if (_mass + mass > 0)
        {
            _mass +=  mass;
        } else
        {
            _mass = MASS_DEFAULT;
            _massDefault = true;
        }

        if (_area > 0)
        {
            _density = _mass / _area;
        }
        else
        {
            _density = 0;
        }
    }

    // the static body's mass and moment is always infinity
    if (_dynamic)
    {
        cpBodySetMass(_cpBody, _mass);
    }
}
Esempio n. 11
0
void Unit::updatePhysics( )
{
	cpBodySetMass( physBody, phys.mass );
	cpFloat moment;
	switch(phys.type){
		case potCircle:
			if( physShape )
				cpCircleShapeSetRadius( physShape, phys.radius );
			moment = cpMomentForCircle( phys.mass, 0, phys.radius, cpvzero );
			break;
		default:
			moment = 1.0;
			break;
	}
	cpBodySetMoment( physBody, moment );
	if( cpBodyIsStatic(physBody) && phys.type != potNone )
		cpSpaceReindexShape( Phys::space, physShape );
}
Esempio n. 12
0
void
cpSpaceConvertBodyToStatic(cpSpace *space, cpBody *body)
{
	cpAssertHard(!cpBodyIsStatic(body), "Body is already static.");
	cpAssertHard(cpBodyIsRogue(body), "Remove the body from the space before calling this function.");
	cpAssertSpaceUnlocked(space);
	
	cpBodySetMass(body, INFINITY);
	cpBodySetMoment(body, INFINITY);
	
	cpBodySetVel(body, cpvzero);
	cpBodySetAngVel(body, 0.0f);
	
	body->node.idleTime = INFINITY;
	CP_BODY_FOREACH_SHAPE(body, shape){
		cpSpatialIndexRemove(space->activeShapes, shape, shape->hashid);
		cpSpatialIndexInsert(space->staticShapes, shape, shape->hashid);
	}
Esempio n. 13
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;
}
Esempio n. 14
0
static void
update(cpSpace *space)
{
	cpFloat tolerance = 2.0;
	
	if(ChipmunkDemoRightClick && cpShapeNearestPointQuery(shape, ChipmunkDemoMouse, NULL) > tolerance){
		cpBody *body = cpShapeGetBody(shape);
		int count = cpPolyShapeGetNumVerts(shape);
		
		// Allocate the space for the new vertexes on the stack.
		cpVect *verts = (cpVect *)alloca((count + 1)*sizeof(cpVect));
		
		for(int i=0; i<count; i++){
			verts[i] = cpPolyShapeGetVert(shape, i);
		}
		
		verts[count] = cpBodyWorld2Local(body, ChipmunkDemoMouse);
		
		// This function builds a convex hull for the vertexes.
		// Because the result array is NULL, it will reduce the input array instead.
		int hullCount = cpConvexHull(count + 1, verts, NULL, NULL, tolerance);
		
		// Figure out how much to shift the body by.
		cpVect centroid = cpCentroidForPoly(hullCount, verts);
		
		// Recalculate the body properties to match the updated shape.
		cpFloat mass = cpAreaForPoly(hullCount, verts)*DENSITY;
		cpBodySetMass(body, mass);
		cpBodySetMoment(body, cpMomentForPoly(mass, hullCount, verts, cpvneg(centroid)));
		cpBodySetPos(body, cpBodyLocal2World(body, centroid));
		
		// Use the setter function from chipmunk_unsafe.h.
		// You could also remove and recreate the shape if you wanted.
		cpPolyShapeSetVerts(shape, hullCount, verts, cpvneg(centroid));
	}
	
	int steps = 1;
	cpFloat dt = 1.0f/60.0f/(cpFloat)steps;
	
	for(int i=0; i<steps; i++){
		cpSpaceStep(space, dt);
	}
}
Esempio n. 15
0
void PhysicsBody::addMass(float mass)
{
    if (mass == PHYSICS_INFINITY)
    {
        _mass = PHYSICS_INFINITY;
        _massDefault = false;
        _density = PHYSICS_INFINITY;
    }
    else if (mass == -PHYSICS_INFINITY)
    {
        return;
    }
    else if (_mass != PHYSICS_INFINITY)
    {
        if (_massDefault)
        {
            _mass = 0;
            _massDefault = false;
        }
        
        if (_mass + mass > 0)
        {
            _mass +=  mass;
        }else
        {
            _mass = MASS_DEFAULT;
            _massDefault = true;
        }
        
        if (_area > 0)
        {
            _density = _mass / _area;
        }
        else
        {
            _density = 0;
        }
    }
    
    cpBodySetMass(_info->body, PhysicsHelper::float2cpfloat(_mass));
}
Esempio n. 16
0
cpBody *
cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
{
	//body->space = NULL;
	//body->shapeList = NULL;
	//body->arbiterList = NULL;
	//body->constraintList = NULL;
	
	//body->velocity_func = cpBodyUpdateVelocity;
	//body->position_func = cpBodyUpdatePosition;
	
	//cpComponentNode node = {NULL, NULL, 0.0f};
	//body->node = node;
	
	body->p = cpvzero;
	body->v = cpvzero;
	body->f = cpvzero;
	
	body->w = 0.0f;
	body->t = 0.0f;
	
	// body->v_bias = cpvzero;
	// body->w_bias = 0.0f;
	
	body->v_limit = (cpFloat)INFINITY;
	body->w_limit = (cpFloat)INFINITY;
	
	body->data = NULL;
	
	// Setters must be called after full initialization so the sanity checks don't assert on garbage data.
	cpBodySetMass(body, m);
	cpBodySetMoment(body, i);
	//cpBodySetAngle(body, 0.0f);
	
	return body;
}
Esempio n. 17
0
static void pullControlPoint(cpShape *shape) {
    int i;
    float origArea, newArea, newMass;
    control_point_t *cp;
    cpPolyShape *ps;
    cpCircleShape *circle;
    cpVect lp;
    cpVect verts[4];
    cpConstraint *mouseJoint;

    mouseJoint = atlMouseJoint();

    if (!mouseJoint) {
        lp = cpBodyWorld2Local(shape->body, atlMouseClickPos());
    } else {
        /* update joint position */
        lp = cpBodyWorld2Local(shape->body, atlMousePos());
        atlRemoveMouseJoint(g_Space);
    }

    atlCreateMouseJoint(g_Space, shape->body, lp);

    cp = (control_point_t *)shape->data;
    ps = (cpPolyShape *)cp->dom->shape;

    control_point_t *circlePoint;

    for (i = 0; i < 4; ++i) {
        verts[i] = cpPolyShapeGetVert((cpShape *)ps, i);
        if (lp.x > 0) {
            if (verts[i].x > 0)
                verts[i].x = lp.x;
            else
                verts[i].x = -lp.x;
        } else if (lp.x < 0) {
            if (verts[i].x < 0)
                verts[i].x = lp.x;
            else
                verts[i].x = -lp.x;
        }

        if (lp.y > 0) {
            if (verts[i].y > 0)
                verts[i].y = lp.y;
            else
                verts[i].y = -lp.y;
        } else if (lp.y < 0) {
            if (verts[i].y < 0)
                verts[i].y = lp.y;
            else
                verts[i].y = -lp.y;
        }

        circlePoint = (control_point_t *)cp->dom->pControlPoints[i];
        circle = (cpCircleShape *)circlePoint->shape;
        cpCircleShapeSetOffset((cpShape *)circle, verts[i]);
    }

    origArea = (fabs(dominoVerts[0].x)+dominoVerts[3].x) *
               (fabs(dominoVerts[0].y)+dominoVerts[1].y);
    newArea = (fabs(verts[0].x)+verts[3].x) *
              (fabs(verts[0].y)+verts[1].y);

    if (newArea > origArea)
        newMass = newArea/origArea * 0.05f;
    else
        newMass = 1.0f;

    cpBodySetMass(cp->dom->body, newMass);
    cpPolyShapeSetVerts((cpShape *)ps, ps->numVerts, verts, cpvzero);
}
Esempio n. 18
0
void cBody::Mass( const cpFloat& mass ) {
	cpBodySetMass( mBody, mass );
}
Esempio n. 19
0
void Body::setMass(cpFloat m)
{
		cpBodySetMass(body,m);
}
Esempio n. 20
0
static VALUE
rb_cpBodySetMass(VALUE self, VALUE val) {
  cpBodySetMass(BODY(self), NUM2DBL(val));
  return val;
}
Esempio n. 21
0
File: physics.c Progetto: 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;
}