Пример #1
0
// Init is called by the demo code to set up the demo.
static cpSpace *
init(void)
{
	// Create an infinite mass body to attach ground segments and other static geometry to.
	// We won't be adding this body to the space, because we don't want it to be simulated at all.
	// Adding bodies to the space simulates them. (fall under the influence of gravity, etc)
	// We want the static body to stay right where it is at all times.
	staticBody = cpBodyNew(INFINITY, INFINITY);
	
	// Create a space, a space is a simulation world. It simulates the motions of rigid bodies,
	// handles collisions between them, and simulates the joints between them.
	space = cpSpaceNew();
	
	// Lets set some parameters of the space:
	// More iterations make the simulation more accurate but slower
	space->iterations = 10;
	// These parameters tune the efficiency of the collision detection.
	// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpSpace
	cpSpaceResizeStaticHash(space, 30.0f, 1000);
	cpSpaceResizeActiveHash(space, 30.0f, 1000);
	// Give it some gravity
	space->gravity = cpv(0, -100);
	
	// Create A ground segment along the bottom of the screen
	cpShape *ground = cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f);
	// Set some parameters of the shape.
	// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpShape
	ground->e = 1.0f; ground->u = 1.0f;
	ground->layers = NOT_GRABABLE_MASK; // Used by the Demo mouse grabbing code
	// Add the shape to the space as a static shape
	// If a shape never changes position, add it as static so Chipmunk knows it only needs to
	// calculate collision information for it once when it is added.
	// Do not change the postion of a static shape after adding it.
	cpSpaceAddStaticShape(space, ground);
	
	// Add a moving circle object.
	cpFloat radius = 15.0f;
	cpFloat mass = 10.0f;
	// This time we need to give a mass and moment of inertia when creating the circle.
	cpBody *ballBody = cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero));
	// Set some parameters of the body:
	// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpBody
	ballBody->p = cpv(0, -240 + radius+5);
	// Add the body to the space so it will be simulated and move around.
	cpSpaceAddBody(space, ballBody);
	
	
	// Add a circle shape for the ball.
	// Shapes are always defined relative to the center of gravity of the body they are attached to.
	// When the body moves or rotates, the shape will move with it.
	// Additionally, all of the cpSpaceAdd*() functions return the thing they added so you can create and add in one go.
	cpShape *ballShape = cpSpaceAddShape(space, cpCircleShapeNew(ballBody, radius, cpvzero));
	ballShape->e = 0.0f; ballShape->u = 0.9f;
	
	return space;
}
Пример #2
0
static cpSpace *
init(void)
{
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	space->iterations = 5;
	space->gravity = cpv(0, -100);
	
	cpSpaceResizeStaticHash(space, 40.0f, 999);
	cpSpaceResizeActiveHash(space, 30.0f, 2999);
	
	cpBody *body, *staticBody = &space->staticBody;
	cpShape *shape;
	
	// Create vertexes for a pentagon shape.
	cpVect verts[NUM_VERTS];
	for(int i=0; i<NUM_VERTS; i++){
		cpFloat angle = -2*M_PI*i/((cpFloat) NUM_VERTS);
		verts[i] = cpv(10*cos(angle), 10*sin(angle));
	}
	
	// Vertexes for a triangle shape.
	cpVect tris[] = {
		cpv(-15,-15),
		cpv(  0, 10),
		cpv( 15,-15),
	};

	// Create the static triangles.
	for(int i=0; i<9; i++){
		for(int j=0; j<6; j++){
			cpFloat stagger = (j%2)*40;
			cpVect offset = cpv(i*80 - 320 + stagger, j*70 - 240);
			shape = cpSpaceAddShape(space, cpPolyShapeNew(staticBody, 3, tris, offset));
			shape->e = 1.0f; shape->u = 1.0f;
			shape->layers = NOT_GRABABLE_MASK;
		}
	}
	
	// Add lots of pentagons.
	for(int i=0; i<300; i++){
		body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, NUM_VERTS, verts, cpvzero)));
		cpFloat x = rand()/(cpFloat)RAND_MAX*640 - 320;
		body->p = cpv(x, 350);
		
		shape = cpSpaceAddShape(space, cpPolyShapeNew(body, NUM_VERTS, verts, cpvzero));
		shape->e = 0.0f; shape->u = 0.4f;
	}
	
	return space;
}
Пример #3
0
/*!
    @method KRSimulator2D
    Constructor
 */
KRSimulator2D::KRSimulator2D(const KRVector2D& gravity)
    : mHasChangedAngle(false)
{
    mCPSpace = cpSpaceNew();
    mCPStaticBody = cpBodyNew(INFINITY, INFINITY);
    
    ((cpSpace*)mCPSpace)->iterations = 20;

	cpSpaceResizeActiveHash((cpSpace*)mCPSpace, 40.0, 1000);
    cpSpaceResizeStaticHash((cpSpace*)mCPSpace, 200.0, 1000);

    setGravity(gravity);
}
Пример #4
0
static cpSpace *
init(void)
{
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	space->iterations = 30;
	cpSpaceResizeStaticHash(space, 40.0f, 1000);
	cpSpaceResizeActiveHash(space, 40.0f, 1000);
	space->gravity = cpv(0, -100);
	space->sleepTimeThreshold = 0.5f;
	
	cpBody *body, *staticBody = &space->staticBody;
	cpShape *shape;
	
	// Create segments around the edge of the screen.
	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;
	
	// Add lots of boxes.
	for(int i=0; i<14; i++){
		for(int j=0; j<=i; j++){
			body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForBox(1.0f, 30.0f, 30.0f)));
			body->p = cpv(j*32 - i*16, 300 - i*32);
			
			shape = cpSpaceAddShape(space, cpBoxShapeNew(body, 30.0f, 30.0f));
			shape->e = 0.0f; shape->u = 0.8f;
		}
	}
	
	// Add a ball to make things more interesting
	cpFloat radius = 15.0f;
	body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero)));
	body->p = cpv(0, -240 + radius+5);

	shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero));
	shape->e = 0.0f; shape->u = 0.9f;
	
	return space;
}
Пример #5
0
static cpSpace *
init(void)
{
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	space->iterations = 5;
	space->gravity = cpv(0, -100);
	
	cpSpaceResizeStaticHash(space, 40.0f, 999);
	cpSpaceResizeActiveHash(space, 30.0f, 2999);
	
	cpBody *body, *staticBody = &space->staticBody;
	cpShape *shape;
	
	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;
	
	for(int i=0; i<NUM_CIRCLES; i++){
		body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForCircle(1.0f, 0.0f, circleRadius, cpvzero)));
		body->p = cpvmult(cpv(frand()*2.0f - 1.0f, frand()*2.0f - 1.0f), circleRadius*5.0f);
		
		circles[i] = shape = cpSpaceAddShape(space, cpCircleShapeNew(body, circleRadius, cpvzero));
		shape->e = 0.0f; shape->u = 1.0f;
	}
	
	strcat(messageString,
		"chipmunk_unsafe.h Contains functions for changing shapes, but they can cause severe stability problems if used incorrectly.\n"
		"Shape changes occur as instantaneous changes to position without an accompanying velocity change. USE WITH CAUTION!");
	return space;
}
Пример #6
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;
}
Пример #7
0
static cpSpace *
init(void)
{
	staticBody = cpBodyNew(INFINITY, INFINITY);
	
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	cpSpaceResizeActiveHash(space, 40.0f, 999);
	cpSpaceResizeStaticHash(space, 40.0f, 99);
	space->gravity = cpv(0, -600);
	
	cpBody *body;
	cpShape *shape;
	
	// Vertexes for the bricks
	int num = 4;
	cpVect verts[] = {
		cpv(-30,-15),
		cpv(-30, 15),
		cpv( 30, 15),
		cpv( 30,-15),
	};
	
	// Set up the static box.
	cpVect a = cpv(-200, -200);
	cpVect b = cpv(-200,  200);
	cpVect c = cpv( 200,  200);
	cpVect d = cpv( 200, -200);
	
	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, a, b, 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, b, c, 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, c, d, 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;

	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, d, a, 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;
	
	// Give the box a little spin.
	// Because staticBody is never added to the space, we will need to
	// update it ourselves. (see above).
	// NOTE: Normally you would want to add the segments as normal and not static shapes.
	// I'm just doing it to demonstrate the cpSpaceRehashStatic() function.
	staticBody->w = 0.4f;
	
	// Add the bricks.
	for(int i=0; i<3; i++){
		for(int j=0; j<7; j++){
			body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
			body->p = cpv(i*60 - 150, j*30 - 150);
			
			shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
			shape->e = 0.0f; shape->u = 0.7f;
		}
	}
	
	return space;
}
Пример #8
0
 void CDynamics2DEngine::Init(TConfigurationNode& t_tree) {
    /* Init parent */
    CPhysicsEngine::Init(t_tree);
    /* Parse XML */
    GetNodeAttributeOrDefault(t_tree, "iterations",       m_nIterations,         m_nIterations);
    GetNodeAttributeOrDefault(t_tree, "static_cell_size", m_fStaticHashCellSize, m_fStaticHashCellSize);
    GetNodeAttributeOrDefault(t_tree, "active_cell_size", m_fActiveHashCellSize, m_fActiveHashCellSize);
    GetNodeAttributeOrDefault(t_tree, "static_cells",     m_nStaticHashCells,    m_nStaticHashCells);
    GetNodeAttributeOrDefault(t_tree, "active_cells",     m_nActiveHashCells,    m_nActiveHashCells);
    GetNodeAttributeOrDefault(t_tree, "elevation",        m_fElevation,          m_fElevation);
    if(NodeExists(t_tree, "boundaries")) {
       /* Parse the boundary definition */
       TConfigurationNode& tBoundaries = GetNode(t_tree, "boundaries");
       SBoundarySegment sBoundSegment;
       CVector2 cLastPoint, cCurPoint;
       std::string strConnectWith;
       TConfigurationNodeIterator tVertexIt("vertex");
       /* Get the first vertex */
       tVertexIt = tVertexIt.begin(&tBoundaries);
       if(tVertexIt == tVertexIt.end()) {
          THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": you didn't specify any <vertex>!");
       }
       GetNodeAttribute(*tVertexIt, "point", cLastPoint);
       m_vecVertices.push_back(cLastPoint);
       /* Go through the other vertices */
       ++tVertexIt;
       while(tVertexIt != tVertexIt.end()) {
          /* Read vertex data and fill in segment struct */
          GetNodeAttribute(*tVertexIt, "point", cCurPoint);
          m_vecVertices.push_back(cCurPoint);
          sBoundSegment.Segment.SetStart(cLastPoint);
          sBoundSegment.Segment.SetEnd(cCurPoint);
          GetNodeAttribute(*tVertexIt, "connect_with", strConnectWith);
          if(strConnectWith == "gate") {
             /* Connect to previous vertex with a gate */
             sBoundSegment.Type = SBoundarySegment::SEGMENT_TYPE_GATE;
             GetNodeAttribute(*tVertexIt, "to_engine", sBoundSegment.EngineId);
          }
          else if(strConnectWith == "wall") {
             /* Connect to previous vertex with a wall */
             sBoundSegment.Type = SBoundarySegment::SEGMENT_TYPE_WALL;
             sBoundSegment.EngineId = "";
          }
          else {
             /* Parse error */
             THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": unknown vertex connection method \"" << strConnectWith << "\". Allowed methods are \"wall\" and \"gate\".");
          }
          m_vecSegments.push_back(sBoundSegment);
          /* Next vertex */
          cLastPoint = cCurPoint;
          ++tVertexIt;
       }
       /* Check that the boundary is a closed path */
       if(m_vecVertices.front() != m_vecVertices.back()) {
          THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": the specified path is not closed. The first and last points of the boundaries MUST be the same.");
       }
    }
    /* Initialize physics */
    cpInitChipmunk();
    cpResetShapeIdCounter();
    /* Used to attach static geometries so that they won't move and to simulate friction */
    m_ptGroundBody = cpBodyNew(INFINITY, INFINITY);
    /* Create the space to contain the movable objects */
    m_ptSpace = cpSpaceNew();
    /* Subiterations to solve constraints.
       The more, the better for precision but the worse for speed
    */
    m_ptSpace->iterations = m_nIterations;
    /* Resize the space hash.
       This has dramatic effects on performance.
       TODO: - find optimal parameters automatically (average entity size)
    */
    cpSpaceResizeStaticHash(m_ptSpace, m_fStaticHashCellSize, m_nStaticHashCells);
    cpSpaceResizeActiveHash(m_ptSpace, m_fActiveHashCellSize, m_nActiveHashCells);
    /* Gripper-Gripped callback functions */
    cpSpaceAddCollisionHandler(
       m_ptSpace,
       SHAPE_MAGNETIC_GRIPPER,
       SHAPE_GRIPPABLE,
       MagneticGripperGrippableCollisionBegin,
       MagneticGripperGrippableCollisionPreSolve,
       NULL,
       NULL,
       NULL);
    /* Add boundaries, if specified */
    if(! m_vecSegments.empty()) {
       cpShape* ptSegment;
       for(size_t i = 0; i < m_vecSegments.size(); ++i) {
          if(m_vecSegments[i].Type == SBoundarySegment::SEGMENT_TYPE_WALL) {
             ptSegment =
                cpSpaceAddShape(
                   m_ptSpace,
                   cpSegmentShapeNew(
                      m_ptGroundBody,
                      cpv(m_vecSegments[i].Segment.GetStart().GetX(),
                          m_vecSegments[i].Segment.GetStart().GetY()),
                      cpv(m_vecSegments[i].Segment.GetEnd().GetX(),
                          m_vecSegments[i].Segment.GetEnd().GetY()),
                      0.0f));
             ptSegment->e = 0.0f; // no elasticity
             ptSegment->u = 1.0f; // max friction
          }
          else {
             /* There is at least a gate, transfer is activated */
             m_bEntityTransferActive = true;
          }
       }
    }
 }
Пример #9
0
static cpSpace *
init(void)
{
	cpResetShapeIdCounter();
	
	space = cpSpaceNew();
	space->iterations = 20;
	cpSpaceResizeActiveHash(space, 30.0f, 2999);
	cpSpaceResizeStaticHash(space, 30.0f, 999);
	space->gravity = cpv(0, -300);

	cpBody *body;
	
	cpShape *shape;
	
	// Vertexes for the dominos.
	int num = 4;
	cpVect verts[] = {
		cpv(-3,-20),
		cpv(-3, 20),
		cpv( 3, 20),
		cpv( 3,-20),
	};
	
	// Add a floor.
	shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(NULL, cpv(-600,-240), cpv(600,-240), 0.0f));
	shape->e = 1.0f; shape->u = 1.0f;
	shape->layers = NOT_GRABABLE_MASK;
	
	// Shared friction constant.
	cpFloat u = 0.6f;
	
	// Add the dominoes. Skim over this. It doesn't do anything fancy, and it's hard to follow.
	int n = 9;
	for(int i=1; i<=n; i++){
		cpVect offset = cpv(-i*60/2.0f, (n - i)*52);
		
		for(int j=0; j<i; j++){
			body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
			body->p = cpvadd(cpv(j*60, -220), offset);
			
			shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
			shape->e = 0.0f; shape->u = u;
			

			body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
			body->p = cpvadd(cpv(j*60, -197), offset);
			cpBodySetAngle(body, M_PI/2.0f);
			
			shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
			shape->e = 0.0f; shape->u = u;
			
			
			if(j == (i - 1)) continue;
			body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
			body->p = cpvadd(cpv(j*60 + 30, -191), offset);
			cpBodySetAngle(body, M_PI/2.0f);
			
			shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
			shape->e = 0.0f; shape->u = u;
		}

		body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
		body->p = cpvadd(cpv(-17, -174), offset);
		
		shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
		shape->e = 0.0f; shape->u = u;
		

		body = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)));
		body->p = cpvadd(cpv((i - 1)*60 + 17, -174), offset);
		
		shape = cpSpaceAddShape(space, cpPolyShapeNew(body, num, verts, cpvzero));
		shape->e = 0.0f; shape->u = u;
	}
	
	// Give the last domino a little tap.
//	body->w = -1;
//	body->v = cpv(-body->w*20, 0);
	return space;
}