Beispiel #1
0
ETERM *body_update_position(ETERM *fromp, ETERM *argp) {

    // get the args
    ETERM *space_refp = erl_element(1, argp);
    ETERM *idp = erl_element(2, argp);
    ETERM *deltap = erl_element(3, argp);

    erlmunk_space *s = NULL;
    int space_id = ERL_REF_NUMBER(space_refp);
    HASH_FIND_INT(erlmunk_spaces, &space_id, s);

    int body_id = ERL_INT_VALUE(idp);
    erlmunk_body *b = NULL;
    HASH_FIND_INT(s->bodies, &body_id, b);
    if (b == NULL)
        return NULL;

    cpVect position = cpBodyGetPosition(b->body);
    float angle = deg_to_rad(cpBodyGetAngle(b->body));
    cpVect angleV = cpvforangle(angle);
    cpVect projection = cpvmult(angleV, ERL_FLOAT_VALUE(deltap));
    cpVect new_position = cpvadd(projection, position);
    cpBodySetPosition(b->body, new_position);

    // DEBUGF(("body_update_position(x: %f, y: %f, delta: %f) has succeeded (x: %f, y: %f)",
    //     position.x, position.y, ERL_FLOAT_VALUE(deltap),
    //     new_position.x, new_position.y));
    return NULL;
}
Beispiel #2
0
void GameTrack::updateCarSensors(GameCar* car) {
	if(!car->getSensorEnabled()) return;
	float* data=car->getSensorData();
	float spread=car->getSensorSpread();
	int pixels=car->getSensorPixels();
	float len=car->getSensorLength();

	cpSpace* space=sim->get_space();
	cpBody* body=car->physic_object->get_body();

	for(int i=0;i<pixels;i++) {
		float angle=car->getSensorAngle(i);

		float y_offset=0.8; //fabs(angle)/45;

		cpVect start={0,y_offset};
		cpVect end=cpvmult(cpvforangle(degToRad(angle)),len);

		start=cpBodyLocal2World(body,start);
		end=cpBodyLocal2World(body,end);

		cpSegmentQueryInfo info;
		cpSpaceSegmentQueryFirst(space,start,end,car->getLayers(),CP_NO_GROUP,&info);

		data[i]=info.t;
	}

}
Beispiel #3
0
ETERM *body_apply_impulse(ETERM *fromp, ETERM *argp) {

    // get the args
    ETERM *space_refp = erl_element(1, argp);
    ETERM *idp = erl_element(2, argp);
    ETERM *impulsep = erl_element(3, argp);

    erlmunk_space *s;
    int space_id = ERL_REF_NUMBER(space_refp);
    HASH_FIND_INT(erlmunk_spaces, &space_id, s);

    int body_id = ERL_INT_VALUE(idp);
    erlmunk_body *b;
    HASH_FIND_INT(s->bodies, &body_id, b);
    if (b == NULL)
        return NULL;

    // apply the impulse at the center of the body and along it's current angle
    float angle = deg_to_rad(cpBodyGetAngle(b->body));
    cpVect angleV = cpvforangle(angle);
    cpVect impulse = cpvmult(angleV, ERL_FLOAT_VALUE(impulsep));
    cpBodyApplyImpulseAtWorldPoint(b->body, impulse, angleV);

    return NULL;
}
Beispiel #4
0
void update_drive()
{
	const cpFloat max_forward_speed = 150;
	const cpFloat max_backward_speed = -20;
	const cpFloat max_drive_force = 100;

	int i;
	for(i=0; i<1; i++) {
		cpFloat desired_speed = 0;

		// find desired speed
		if(controls.forward)
			desired_speed = max_forward_speed;
		else if(controls.back)
			desired_speed = max_backward_speed;

		// find speed
		cpVect forward_normal = cpvperp(cpvforangle(cpBodyGetAngle(tire[i])));
		cpFloat speed = cpvdot(forward_velocity(i), forward_normal);

		// apply force
		cpFloat force = 0;
		if(desired_speed > speed)
			force = max_drive_force;
		else if(desired_speed < speed)
			force = -max_drive_force;
		else
			return;
		cpBodyApplyImpulse(tire[i], cpvmult(forward_normal, force), cpvzero);
	}
}
Beispiel #5
0
void draw_shape(cpBody* body, cpShape* shape, void* data)
{
	// get body info
	cpVect v = cpBodyGetPos(body);
	cpFloat angle = cpBodyGetAngle(body);
	cpVect rot = cpvforangle(angle);

	// get vectors
	int n = cpPolyShapeGetNumVerts(shape); 
	SDL_Point* pts = calloc(sizeof(SDL_Point), n+1);

	// rotate vectors
	int i;
	for(i=0; i<n; i++) {
		cpVect p = cpPolyShapeGetVert(shape, i);
		cpVect vr = cpvrotate(cpv(p.x,p.y), rot);
		pts[i] = (SDL_Point) { (vr.x+v.x)*10+50, (vr.y+v.y)*10+50 };
		if(i == 0)
			pts[n] = pts[i];
	}

	// draw
	SDL_RenderDrawLines(ren, pts, n+1);

	free(pts);
}
// returns the transform matrix according the Chipmunk Body values
CCAffineTransform CCPhysicsSprite::nodeToParentTransform()
{
    cpVect rot = (m_bIgnoreBodyRotation ? cpvforangle(-CC_DEGREES_TO_RADIANS(m_fRotationX)) : m_pCPBody->rot);
    float x = m_pCPBody->p.x + rot.x*(-m_obAnchorPointInPoints.x) - rot.y*(-m_obAnchorPointInPoints.y);
    float y = m_pCPBody->p.y + rot.y*(-m_obAnchorPointInPoints.x) + rot.x*(-m_obAnchorPointInPoints.y);
    
    if (m_bIgnoreAnchorPointForPosition)
    {
        x += m_obAnchorPointInPoints.x;
        y += m_obAnchorPointInPoints.y;
    }
    
    return (m_sTransform = CCAffineTransformMake(rot.x, rot.y, -rot.y, rot.x, x, y));
}
CCAffineTransform cpCCNode::nodeToParentTransform ( KDvoid )
{
	cpBody*  pBody = m_pImplementation->getBody ( );
	cpVect   tRot  = m_pImplementation->isIgnoreRotation ( ) ? cpvforangle ( -CC_DEGREES_TO_RADIANS ( m_tRotation.x ) ) : pBody->rot;

	KDfloat  x = pBody->p.x + tRot.x * -m_tAnchorPointInPoints.x - tRot.y * - m_tAnchorPointInPoints.y;
	KDfloat  y = pBody->p.y + tRot.y * -m_tAnchorPointInPoints.x + tRot.x * - m_tAnchorPointInPoints.y;

	if ( m_pImplementation->isIgnoreRotation ( ) )
	{
		x += m_tAnchorPointInPoints.x;
		y += m_tAnchorPointInPoints.y;
	}

	m_tTransform = CCAffineTransformMake ( tRot.x, tRot.y, -tRot.y, tRot.x, x, y );

	return m_tTransform;
}
Beispiel #8
0
// returns the transform matrix according the Chipmunk Body values
CCAffineTransform CCPhysicsSprite::nodeToParentTransform()
{
    // Although scale is not used by physics engines, it is calculated just in case
	// the sprite is animated (scaled up/down) using actions.
	// For more info see: http://www.cocos2d-iphone.org/forum/topic/68990
	cpVect rot = (m_bIgnoreBodyRotation ? cpvforangle(-CC_DEGREES_TO_RADIANS(m_fRotationX)) : m_pCPBody->rot);
	float x = m_pCPBody->p.x + rot.x * -m_obAnchorPointInPoints.x * m_fScaleX - rot.y * -m_obAnchorPointInPoints.y * m_fScaleY;
	float y = m_pCPBody->p.y + rot.y * -m_obAnchorPointInPoints.x * m_fScaleX + rot.x * -m_obAnchorPointInPoints.y * m_fScaleY;
	
	if (m_bIgnoreAnchorPointForPosition)
    {
		x += m_obAnchorPointInPoints.x;
		y += m_obAnchorPointInPoints.y;
	}
	
	return (m_sTransform = CCAffineTransformMake(rot.x * m_fScaleX, rot.y * m_fScaleX,
                                                 -rot.y * m_fScaleY, rot.x * m_fScaleY,
                                                 x,	y));
}
Beispiel #9
0
void Bomb::explode(int timestep) {
  exploding = true; 
  cpVect blast_dir;
  
  for (int j=0; j < PARTICLE_TOTAL; j++) {
    if (particles[j]->dead) {
      blast_dir = cpvmult(cpvforangle(DEG2RAD(j*3)), (rand()%100)+40);
      particles[j]->x = x;
      particles[j]->y = y;
      particles[j]->x_speed = blast_dir.x;
      particles[j]->y_speed = blast_dir.y;
      particles[j]->ttl = 1250;
      particles[j]->birth = timestep;
      particles[j]->color = 100;
      particles[j]->dead = false;
    }
  }
  
}
Beispiel #10
0
void
cpBodySetAngle(cpBody *body, cpFloat a)
{
	body->a = fmod(a, (cpFloat)M_PI*2.0f);
	body->rot = cpvforangle(a);
}
Beispiel #11
0
static void update(void) {
    int steps, i;
    cpFloat dt;
    cpVect look, lastPos, curPos;
    projectile_t *pj; /* temp for looping */

    static cpVect delta = {0, 0};
    static projectile_t *curProj = NULL;
    static bool canToggleEditor = true;

    curPos = atlMousePos();
    lastPos = atlMouseLastPos();

    /* rotate 'gun' based on mouse position */
    look = cpvnormalize(cpvsub(curPos, g_Cannon->body->p));
    cpBodySetAngle(g_Cannon->body, cpvtoangle(look));

    if (isKeyPressed(KEY_e) && canToggleEditor) {
        canToggleEditor = false;
        editorMode = !editorMode;
    } else if (!isKeyPressed(KEY_e)) {
        canToggleEditor = true;
    }

    if (editorMode) {
        if (!editorBody)
            initializeEditor();
        handleEditor();
    } else {
        if (editorBody)
            destroyEditor();

        if (atlLeftMouseDown()) {

            if (!curProj) {
                /* don't let player hold the left mouse button to fire multiple rounds */
                delta = cpvnormalize(cpvsub(atlMouseClickPos(), g_Cannon->body->p));
                if (g_Cannon->ai < MAX_PROJECTILES) {
                    curProj = g_Cannon->ammo[g_Cannon->ai++];

                    if (curProj) {
                        cpSpaceAddBody(g_Space, curProj->body);
                        curProj->body->p = cpvadd(g_Cannon->body->p,
                                                  cpvmult(look, g_Cannon->length));

                        cpSpaceAddShape(g_Space, curProj->shape);
                        cpBodyApplyImpulse(curProj->body,
                                           cpvmult(cpvforangle(g_Cannon->body->a), 600.0f),
                                           cpvzero);
                        cpBodyActivate(curProj->body);
                    }
                }
            }
        } else {
            curProj = NULL;
        }
    }

    /* treat projectiles as limited resources. only allocated at the start of a level */
    for (i = 0; i <= g_Cannon->ai-1; ++i) {
        pj = g_Cannon->ammo[i];
        if (!pj)
            continue;

        if (pj->body->v.x >= -0.01f && pj->body->v.x <= 0.01f &&
            pj->body->v.y >= -0.01f && pj->body->v.y <= 0.01f) {
            /* TODO: mark an object for deletion, but don't delete immediately */
            cpSpaceRemoveBody(g_Space, pj->body);
            cpSpaceRemoveShape(g_Space, pj->shape);
            free(g_Cannon->ammo[i]);
            g_Cannon->ammo[i] = NULL;
        }
    }

    steps = 3;
    dt = 1.0f/60.0f/(cpFloat)steps;

    for (i = 0; i < steps; ++i) {
        cpSpaceStep(g_Space, dt);
    }
}
Beispiel #12
0
static void
draw_shape(cpShape* shape, SDL_Surface* screen)
{
    cpBody* body = shape->body;
    struct draw_options opts = {
        .surface = screen,
        .colour = colour(200, 200, 200)
    };

    switch (shape->CP_PRIVATE(klass)->type)
    {
        case CP_CIRCLE_SHAPE:
            draw_circle_shape(opts, shape, body);
            break;
        case CP_SEGMENT_SHAPE:
            draw_segment_shape(opts, shape, body);
            break;
        case CP_POLY_SHAPE:
            draw_poly_shape(opts, shape, body);
            break;
        default:
            debug_putsf("ignoring unrecognised shape type %d",
                    shape->CP_PRIVATE(klass)->type);
            break;
    }
}

static void
draw_constraint(cpConstraint* constraint, SDL_Surface *screen)
{
    struct draw_options opts = {
        .surface = screen,
        .colour = colour(100, 100, 200)
    };

    cpVect vect_a = cpBodyGetPos(cpConstraintGetA(constraint));
    cpVect vect_b = cpBodyGetPos(cpConstraintGetB(constraint));
    draw_line(opts, vect_a, vect_b);
}

static void
draw_rotation_vector(cpBody *body, SDL_Surface *screen)
{
    struct draw_options opts = {
        .surface = screen,
        .colour = colour(200, 100, 100)
    };

    cpFloat rotation_vector_length = 30;
    cpVect pos = cpBodyGetPos(body);
    cpVect rotation = cpvmult(cpvforangle(cpBodyGetAngle(body)),
                              rotation_vector_length);
    draw_line(opts, pos, cpvadd(pos, rotation));
}

static void
draw_forces(cpBody *body, SDL_Surface *screen)
{
    struct draw_options opts = {
        .surface = screen,
        .colour = colour(100, 200, 100)
    };

    cpVect pos = cpBodyGetPos(body);
    cpVect force = cpBodyGetForce(body);
    draw_line(opts, pos, cpvadd(pos, force));
}

static void
draw_body(cpBody *body, SDL_Surface *screen)
{
    draw_rotation_vector(body, screen);
    draw_forces(body, screen);
}

void
debug_draw_space(cpSpace* space, SDL_Surface* screen)
{
    cpSpaceEachShape(space,
        (cpSpaceShapeIteratorFunc)draw_shape,
        screen);
    cpSpaceEachConstraint(space,
        (cpSpaceConstraintIteratorFunc)draw_constraint,
        screen);
    cpSpaceEachBody(space,
        (cpSpaceBodyIteratorFunc)draw_body,
        screen);
}
Beispiel #13
0
cpVect cpvrotate(cpVect v, float a)
{
	return cpvrotate(v, cpvforangle(a));
}
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;
}
Beispiel #15
0
cpVect forward_velocity(int n)
{
	cpVect normal = cpvperp(cpvforangle(cpBodyGetAngle(tire[n])));
	return cpvmult(normal, cpvdot(normal, cpBodyGetVel(tire[n])));
}
Beispiel #16
0
cpVect lateral_velocity(int n)
{
	cpVect normal = cpvforangle(cpBodyGetAngle(tire[n]));
	return cpvmult(normal, cpvdot(normal, cpBodyGetVel(tire[n])));
}
 CDynamics2DBoxEntity::CDynamics2DBoxEntity(CDynamics2DEngine& c_engine,
                                            CBoxEntity& c_entity) :
    CDynamics2DEntity(c_engine, c_entity.GetEmbodiedEntity()),
    m_cBoxEntity(c_entity),
    m_fMass(c_entity.GetMass()),
    m_ptShape(NULL),
    m_ptBody(NULL) {
    /* Get the size of the entity */
    CVector3 cHalfSize = c_entity.GetSize() * 0.5f;
    m_fHalfHeight = cHalfSize.GetZ();
    /* Create a polygonal object in the physics space */
    /* Start defining the vertices
       NOTE: points must be defined in a clockwise winding
    */
    cpVect tVertices[] = {
       cpv(-cHalfSize.GetX(), -cHalfSize.GetY()),
       cpv(-cHalfSize.GetX(),  cHalfSize.GetY()),
       cpv( cHalfSize.GetX(),  cHalfSize.GetY()),
       cpv( cHalfSize.GetX(), -cHalfSize.GetY())
    };
    const CVector3& cPosition = GetEmbodiedEntity().GetPosition();
    CRadians cXAngle, cYAngle, cZAngle;
    GetEmbodiedEntity().GetOrientation().ToEulerAngles(cZAngle, cYAngle, cXAngle);
    if(c_entity.GetEmbodiedEntity().IsMovable()) {
       /* The box is movable */
       /* Create the body */
       m_ptBody =
          cpSpaceAddBody(m_cEngine.GetPhysicsSpace(),
                         cpBodyNew(m_fMass,
                                   cpMomentForPoly(m_fMass,
                                                   4,
                                                   tVertices,
                                                   cpvzero)));
       m_ptBody->p = cpv(cPosition.GetX(), cPosition.GetY());
       cpBodySetAngle(m_ptBody, cZAngle.GetValue());
       /* Create the geometry */
       m_ptShape =
          cpSpaceAddShape(m_cEngine.GetPhysicsSpace(),
                          cpPolyShapeNew(m_ptBody,
                                         4,
                                         tVertices,
                                         cpvzero));
       /* This object is grippable */
       m_ptShape->collision_type = CDynamics2DEngine::SHAPE_GRIPPABLE;
       m_ptShape->data = reinterpret_cast<void*>(&c_entity);
       /* No elasticity */
       m_ptShape->e = 0.0;
       /* Lots contact friction to help pushing */
       m_ptShape->u = 0.7;
       /* Friction with ground */
       m_ptLinearFriction =
          cpSpaceAddConstraint(m_cEngine.GetPhysicsSpace(),
                               cpPivotJointNew2(m_cEngine.GetGroundBody(),
                                                m_ptBody,
                                                cpvzero,
                                                cpvzero));
       m_ptLinearFriction->maxBias = 0.0f; // disable joint correction
       m_ptLinearFriction->maxForce = 1.49f; // emulate linear friction (this is just slightly smaller than FOOTBOT_MAX_FORCE)
       m_ptAngularFriction =
          cpSpaceAddConstraint(m_cEngine.GetPhysicsSpace(),
                               cpGearJointNew(m_cEngine.GetGroundBody(),
                                              m_ptBody,
                                              0.0f,
                                              1.0f));
       m_ptAngularFriction->maxBias = 0.0f; // disable joint correction
       m_ptAngularFriction->maxForce = 1.49f; // emulate angular friction (this is just slightly smaller than FOOTBOT_MAX_TORQUE)
    }
    else {
       /* The box is not movable */
       /* Manually rotate the vertices */
       cpVect tRot = cpvforangle(cZAngle.GetValue());
       tVertices[0] = cpvrotate(tVertices[0], tRot);
       tVertices[1] = cpvrotate(tVertices[1], tRot);
       tVertices[2] = cpvrotate(tVertices[2], tRot);
       tVertices[3] = cpvrotate(tVertices[3], tRot);
       /* Create the geometry */
       m_ptShape =
          cpSpaceAddStaticShape(m_cEngine.GetPhysicsSpace(),
                                cpPolyShapeNew(m_cEngine.GetGroundBody(),
                                               4,
                                               tVertices,
                                               cpv(cPosition.GetX(), cPosition.GetY())));
       /* This object is normal */
       m_ptShape->collision_type = CDynamics2DEngine::SHAPE_NORMAL;
       m_ptShape->data = reinterpret_cast<void*>(&c_entity);
       /* No elasticity */
       m_ptShape->e = 0.0;
       /* Little contact friction to help sliding away */
       m_ptShape->u = 0.1;
    }
 }
Beispiel #18
0
static inline void
setAngle(cpBody *body, cpFloat angle)
{
	body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
	body->rot = cpvforangle(angle);
}
Beispiel #19
0
static int cpVect_forangle(lua_State *L) {
  cpFloat a = (cpFloat)luaL_checknumber(L, 1);
  push_cpVect(L, cpvforangle(a));
  return 2;
}
Beispiel #20
0
void landerUpdate(Lander l)
{
    cpVect force = cpvmult(cpvforangle(radiansFromOrientation(l->orientation)), l->thrust);
    cpBodyApplyImpulse(l->body, force, cpvzero);
}