예제 #1
0
파일: physics.c 프로젝트: andi2/cgame
void physics_add(Entity ent)
{
    PhysicsInfo *info;

    if (entitypool_get(pool, ent))
        return; /* already has physics */

    transform_add(ent);

    info = entitypool_add(pool, ent);

    info->mass = 1.0;
    info->type = PB_DYNAMIC;

    /* create, init cpBody */
    info->body = cpSpaceAddBody(space, cpBodyNew(info->mass, 1.0));
    cpBodySetUserData(info->body, ent); /* for cpBody -> Entity mapping */
    cpBodySetPos(info->body, cpv_of_vec2(transform_get_position(ent)));
    cpBodySetAngle(info->body, transform_get_rotation(ent));
    info->last_dirty_count = transform_get_dirty_count(ent);

    /* initially no shapes */
    info->shapes = array_new(ShapeInfo);

    /* initialize last_pos/last_ang info for kinematic bodies */
    info->last_pos = cpBodyGetPos(info->body);
    info->last_ang = cpBodyGetAngle(info->body);

    info->collisions = NULL;
}
예제 #2
0
ETERM *space_add_body(ETERM *fromp, ETERM *argp) {

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

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

    int object_id = ERL_INT_VALUE(idp);

    cpBody *body = cpSpaceAddBody(s->space,
                                  cpBodyNew(ERL_FLOAT_VALUE(massp),
                                            INFINITY));
    // the body is created inactive, it is explicitly activated
    // when all it's values have been set.
    cpBodySleep(body);
    erlmunk_body_data *data = malloc(sizeof(erlmunk_body_data));
    data->id = object_id;
    data->term = NULL;
    cpBodySetUserData(body, (cpDataPointer) data);
    space_add_body_hash(s, object_id, body);

    return NULL;
}
예제 #3
0
void RCPBody::setUserData(cpDataPointer data)
{
    mUserData = data;
    if (mBody) {
        cpBodySetUserData(mBody, mUserData);
    }
}
예제 #4
0
파일: particle.c 프로젝트: niksaak/dame
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++;
}
예제 #5
0
	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;
	}
예제 #6
0
cpBody* drawing_update(cpSpace *space, cpBody *drawing, cpFloat x, cpFloat y) {
    Body_data *pa = cpBodyGetUserData(drawing);
    int length = pa->x_values->len;
	cpVect old = cpvzero;
    old.x = g_array_index(pa->x_values, cpFloat, length - 1);
	old.y = g_array_index(pa->y_values, cpFloat, length - 1);

	old = cpBodyLocal2World(drawing, old);
	cpVect point = cpv(x, y);
    // if the difference between the new x and the previous x is greater than the threshold
    if (cpvdistsq(old, point) > THRESHOLD) {
        
		cpVect position = cpBodyGetPos(drawing);

		point = cpvsub(point, position);
		//cpBodyWorld2Local(drawing, point);
		fprintf(stdout, "Point= (%5.2f, %5.2f) while x= %5.2f, y=%5.2f\n", point.x, point.y, x, y);
		x = point.x;
		y = point.y;
		    g_array_append_val(pa->x_values, x);
		    g_array_append_val(pa->y_values, y);
		    cpBodySetUserData(drawing, pa);
	
		    drawing = add_segment_to_body(space, drawing);
    }
    cpBodySetVel(drawing, cpvzero);
    
    return drawing;
}
예제 #7
0
cpBody* createNewBodyFrom(cpSpace* space, cpFloat xPos, cpFloat yPos, cpFloat mass, cpFloat moment, JSObject* outterJsObj)
{
  cpBody* circularBody = cpSpaceAddBody(space, cpBodyNew(mass, moment));
  cpBodySetPos(circularBody, cpv(xPos, yPos));

  cpBodySetUserData(circularBody, outterJsObj);
  return circularBody;
}
예제 #8
0
Space::Space(void)
	: space(cpSpaceNew()),
	  data(0),
	  body(new cp::Body(cpSpaceGetStaticBody(space)))
{
		space->data = this;
		cpBodySetUserData(cpSpaceGetStaticBody(space), body);
}
예제 #9
0
cpBody* drawing_new(cpFloat x, cpFloat y, long color_rgb) {
    cpBody *drawing = cpBodyNew(INITIAL, INITIAL);
    cpBodySetPos(drawing, cpv(x, y));
    
    Point_array *pa = point_array_new(x, y, color_rgb);
    cpBodySetUserData(drawing, pa);
    
    return drawing;
}
예제 #10
0
	cpBody* RigidBody2D::Create(float mass, float moment)
	{
		cpBody* handle = cpBodyNew(mass, moment);
		cpBodySetUserData(handle, this);

		if (mass <= 0.f)
			cpBodySetType(handle, CP_BODY_TYPE_KINEMATIC);

		cpSpaceAddBody(m_world->GetHandle(), handle);

		return handle;
	}
예제 #11
0
cpBody* drawing_new(cpFloat x, cpFloat y, long color_rgb) {
    cpBody *drawing = cpBodyNew(INITIAL, INITIAL);
	cpVect clickpoint = cpv(x, y);
    cpBodySetPos(drawing, clickpoint);
	cpVect position = cpBodyGetPos(drawing);
	fprintf(stdout, "INITIAL POSITION AT: (%5.2f, %5.2f)\n\n", position.x, position.y);

    Body_data *pa = point_array_new(0, 0, color_rgb);
    cpBodySetUserData(drawing, pa);
    
    return drawing;
}
예제 #12
0
 Player::Player(Entity * e):
     mVel(cpvzero),
     mEntity(e),
     Rpressed(false),
     Lpressed(false),
     mFiredNumber(0),
     mVectp(cpvzero),
     mHp(1000),
     mMaxHp(1000),
     mHpLossTimer(150)
 {
     cpBodySetUserData(mEntity->body(), this);
 }
예제 #13
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;
}
예제 #14
0
ETERM *space_add_boundaries(ETERM *fromp, ETERM *argp) {

    // get the args
    ETERM *space_refp = erl_element(1, argp);
    ETERM *lower_leftp = erl_element(2, argp);
    ETERM *lower_rightp = erl_element(3, argp);
    ETERM *upper_leftp = erl_element(4, argp);
    ETERM *upper_rightp = erl_element(5, argp);
    ETERM *collision_categoryp = erl_element(6, argp);
    ETERM *datap = erl_element(7, argp);

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

    cpVect lowerLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_leftp)),
                           ERL_FLOAT_VALUE(erl_element(2, lower_leftp)));
    cpVect lowerRight = cpv(ERL_FLOAT_VALUE(erl_element(1, lower_rightp)),
                            ERL_FLOAT_VALUE(erl_element(2, lower_rightp)));
    cpVect upperLeft = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_leftp)),
                           ERL_FLOAT_VALUE(erl_element(2, upper_leftp)));
    cpVect upperRight = cpv(ERL_FLOAT_VALUE(erl_element(1, upper_rightp)),
                            ERL_FLOAT_VALUE(erl_element(2, upper_rightp)));

    // get the static body that comes with the space
    cpBody *static_body = cpSpaceGetStaticBody(s->space);
    erlmunk_body_data *data = malloc(sizeof(erlmunk_body_data));
    data->id = BOUNDARY_BODY_ID;
    data->term = erl_copy_term(datap);
    cpBodySetUserData(static_body, (cpDataPointer) data);

    // bottom
    cpShape *bottomBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, lowerRight, 0.0f);
    cpShapeSetCollisionType(bottomBoundaryShape, ERL_INT_VALUE(collision_categoryp));
    cpSpaceAddShape(s->space, bottomBoundaryShape);
    // top
    cpShape *topBoundaryShape = cpSegmentShapeNew(static_body, upperLeft, upperRight, 0.0f);
    cpShapeSetCollisionType(topBoundaryShape, ERL_INT_VALUE(collision_categoryp));
    cpSpaceAddShape(s->space, topBoundaryShape);
    // left
    cpShape *leftBoundaryShape = cpSegmentShapeNew(static_body, lowerLeft, upperLeft, 0.0f);
    cpShapeSetCollisionType(leftBoundaryShape, ERL_INT_VALUE(collision_categoryp));
    cpSpaceAddShape(s->space, leftBoundaryShape);
    // right
    cpShape *rightBoundaryShape = cpSegmentShapeNew(static_body, lowerRight, upperRight, 0.0f);
    cpShapeSetCollisionType(rightBoundaryShape, ERL_INT_VALUE(collision_categoryp));
    cpSpaceAddShape(s->space, rightBoundaryShape);

    return NULL;
}
예제 #15
0
bool PhysicsBody::init()
{
    do
    {
        _cpBody = cpBodyNew(_mass, _moment);
        internalBodySetMass(_cpBody, _mass);
        cpBodySetUserData(_cpBody, this);
        cpBodySetVelocityUpdateFunc(_cpBody, internalBodyUpdateVelocity);
        
        CC_BREAK_IF(_cpBody == nullptr);
        
        return true;
    } while (false);
    
    return false;
}
예제 #16
0
	cpBody* RigidBody2D::Create(float mass, float moment)
	{
		cpBody* handle;
		if (IsKinematic())
		{
			if (IsStatic())
				handle = cpBodyNewStatic();
			else
				handle = cpBodyNewKinematic();
		}
		else
			handle = cpBodyNew(mass, moment);

		cpBodySetUserData(handle, this);

		return handle;
	}
예제 #17
0
파일: kitty.cpp 프로젝트: teritriano/ftf
fff::kitty::kitty(){
    body = cpBodyNew(1.f, INFINITY);
    cpBodySetUserData(body, this);
    
    forecastspace = cpSpaceNew();
    cpSpaceSetIterations(forecastspace, 100);
    cpBodyInit(&forecastbody, 1.f, INFINITY);
    cpSpaceSetGravity(forecastspace, (cpVect){0.f, METERSTOPIXELS(10.f)} );
    cpSpaceAddBody(forecastspace, &forecastbody);
    
    iflames = 0;
    burstinflames = false;
    
    leftimpulse = false;
    rightimpulse = false;

}
예제 #18
0
cpBody* drawing_update(cpSpace *space, cpBody *drawing, cpFloat x, cpFloat y) {
    Point_array *pa = cpBodyGetUserData(drawing);
    int length = pa->x_values->len;
    
    // if the difference between the new x and the previous x is greater than the threshold
    if (( abs((SCALE * x) - (SCALE * g_array_index(pa->x_values, cpFloat, length - 1))) >= (SCALE * THRESHOLD) ) ||
        ( abs((SCALE * y) - (SCALE * g_array_index(pa->y_values, cpFloat, length - 1))) >= (SCALE * THRESHOLD) )) {
        
        g_array_append_val(pa->x_values, x);
        g_array_append_val(pa->y_values, y);
        cpBodySetUserData(drawing, pa);
        
        drawing = add_segment_to_body(space, drawing);
    }
    cpBodySetVel(drawing, cpvzero);
    
    return drawing;
}
예제 #19
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;
}
예제 #20
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);
	}
예제 #21
0
ETERM *body_set_user_data(ETERM *fromp, ETERM *argp) {

    // get the args
    ETERM *space_refp = erl_element(1, argp);
    ETERM *idp = erl_element(2, argp);
    ETERM *datap = 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;

    erlmunk_body_data *data = cpBodyGetUserData(b->body);
    data->term = erl_copy_term(datap);
    cpBodySetUserData(b->body, (cpDataPointer) data);

    return NULL;
}
예제 #22
0
void Body::setup(cpSpace *space, cpBody *b){
	body = cpSpaceAddBody(space, b);
	cpBodySetUserData(body, this);
}