Example #1
0
	Rectf RigidBody2D::GetAABB() const
	{
		if (m_shapes.empty())
			return Rectf::Zero();

		auto it = m_shapes.begin();
		cpBB bb = cpShapeGetBB(*it++);
		for (; it != m_shapes.end(); ++it)
			bb = cpBBMerge(bb, cpShapeGetBB(*it));

		return Rectf(Rect<cpFloat>(bb.l, bb.b, bb.r - bb.l, bb.t - bb.b));
	}
static void
BallIterator(cpBody *body, cpArbiter *arb, int *count)
{
    // body is the body we are iterating the arbiters for.
    // CP_ARBITER_GET_*() in an arbiter iterator always returns the body/shape for the iterated body first.
    CP_ARBITER_GET_SHAPES(arb, ball, other);
    ChipmunkDebugDrawBB(cpShapeGetBB(other), RGBAColor(1, 0, 0, 1));

    (*count)++;
}
 void CDynamics2DSingleBodyObjectModel::MoveTo(const CVector3& c_position,
                                               const CQuaternion& c_orientation) {
    /* Move the body to the desired position */
    m_ptBody->p = cpv(c_position.GetX(), c_position.GetY());
    CRadians cXAngle, cYAngle, cZAngle;
    c_orientation.ToEulerAngles(cZAngle, cYAngle, cXAngle);
    cpBodySetAngle(m_ptBody, cZAngle.GetValue());
    /* Update shape index */
    if(cpBodyIsStatic(m_ptBody)) {
       cpBB tBoundingBox = cpShapeGetBB(m_ptBody->shapeList);
       cpSpaceReindexStatic(GetDynamics2DEngine().GetPhysicsSpace());
       tBoundingBox = cpShapeGetBB(m_ptBody->shapeList);
    }
    else {
       cpSpaceReindexShapesForBody(GetDynamics2DEngine().GetPhysicsSpace(), m_ptBody);
    }
    /* Update ARGoS entity state */
    CDynamics2DModel::UpdateEntityStatus();
 }
 void CDynamics2DSingleBodyObjectModel::CalculateBoundingBox() {
    cpBB tBoundingBox = cpShapeGetBB(m_ptBody->shapeList);
    for(cpShape* pt_shape = m_ptBody->shapeList->next;
        pt_shape != NULL;
        pt_shape = pt_shape->next) {
       cpBB* ptBB = &pt_shape->bb;
       if(ptBB->l < tBoundingBox.l) tBoundingBox.l = ptBB->l;
       if(ptBB->b < tBoundingBox.b) tBoundingBox.b = ptBB->b;
       if(ptBB->r > tBoundingBox.r) tBoundingBox.r = ptBB->r;
       if(ptBB->t > tBoundingBox.t) tBoundingBox.t = ptBB->t;
    }
    GetBoundingBox().MinCorner.SetX(tBoundingBox.l);
    GetBoundingBox().MinCorner.SetY(tBoundingBox.b);
    GetBoundingBox().MaxCorner.SetX(tBoundingBox.r);
    GetBoundingBox().MaxCorner.SetY(tBoundingBox.t);
 }
Example #5
0
static void
BallIterator(cpBody *body, cpArbiter *arb, int *count)
{
	// body is the body we are iterating the arbiters for.
	// CP_ARBITER_GET_*() in an arbiter iterator always returns the body/shape for the iterated body first.
	CP_ARBITER_GET_SHAPES(arb, ball, other);
	
	// Grab the bounding box, expand it slightly (for visibility) and draw it.
	cpBB bb = cpShapeGetBB(other);
	bb.l -= 5.0;
	bb.b -= 5.0;
	bb.r += 5.0;
	bb.t += 5.0;
	
	ChipmunkDebugDrawBB(bb, RGBAColor(1, 0, 0, 1));
	
	(*count)++;
}
Example #6
0
static void
draw(void)
{
	ChipmunkDemoDefaultDrawImpl();
	
	cpVect start = QUERY_START;
	cpVect end = ChipmunkDemoMouse;
	ChipmunkDebugDrawSegment(start, end, RGBAColor(0,1,0,1));
	
	ChipmunkDemoPrintString("Query: Dist(%f) Point%s, ", cpvdist(start, end), cpvstr(end));
	
	cpSegmentQueryInfo segInfo = {};
	if(cpSpaceSegmentQueryFirst(space, start, end, CP_ALL_LAYERS, CP_NO_GROUP, &segInfo)){
		cpVect point = cpSegmentQueryHitPoint(start, end, segInfo);
		
		// Draw red over the occluded part of the query
		ChipmunkDebugDrawSegment(point, end, RGBAColor(1,0,0,1));
		
		// Draw a little blue surface normal
		ChipmunkDebugDrawSegment(point, cpvadd(point, cpvmult(segInfo.n, 16)), RGBAColor(0,0,1,1));
		
		// Draw a little red dot on the hit point.
		ChipmunkDebugDrawPoints(3, 1, &point, RGBAColor(1,0,0,1));

		
		ChipmunkDemoPrintString("Segment Query: Dist(%f) Normal%s", cpSegmentQueryHitDist(start, end, segInfo), cpvstr(segInfo.n));
	} else {
		ChipmunkDemoPrintString("Segment Query (None)");
	}
	
	cpNearestPointQueryInfo nearestInfo = {};
	cpSpaceNearestPointQueryNearest(space, ChipmunkDemoMouse, 100.0, CP_ALL_LAYERS, CP_NO_GROUP, &nearestInfo);
	if(nearestInfo.shape){
		// Draw a grey line to the closest shape.
		ChipmunkDebugDrawPoints(3, 1, &ChipmunkDemoMouse, RGBAColor(0.5, 0.5, 0.5, 1.0));
		ChipmunkDebugDrawSegment(ChipmunkDemoMouse, nearestInfo.p, 	RGBAColor(0.5, 0.5, 0.5, 1.0));
		
		// Draw a red bounding box around the shape under the mouse.
		if(nearestInfo.d < 0) ChipmunkDebugDrawBB(cpShapeGetBB(nearestInfo.shape), RGBAColor(1,0,0,1));
	}
}
 void CDynamics2DMultiBodyObjectModel::CalculateBoundingBox() {
    if(m_vecBodies.empty()) return;
    cpBB tBoundingBox;
    Real fMaxHeight;
    for(size_t i = 0; i < m_vecBodies.size(); ++i) {
       tBoundingBox = cpShapeGetBB(m_vecBodies[i].Body->shapeList);
       for(cpShape* pt_shape = m_vecBodies[i].Body->shapeList->next;
           pt_shape != NULL;
           pt_shape = pt_shape->next) {
          cpBB* ptBB = &pt_shape->bb;
          if(ptBB->l < tBoundingBox.l) tBoundingBox.l = ptBB->l;
          if(ptBB->b < tBoundingBox.b) tBoundingBox.b = ptBB->b;
          if(ptBB->r > tBoundingBox.r) tBoundingBox.r = ptBB->r;
          if(ptBB->t > tBoundingBox.t) tBoundingBox.t = ptBB->t;
       }
       fMaxHeight = Max(fMaxHeight, m_vecBodies[i].Height);
    }      
    GetBoundingBox().MinCorner.SetX(tBoundingBox.l);
    GetBoundingBox().MinCorner.SetY(tBoundingBox.b);
    GetBoundingBox().MinCorner.SetZ(GetDynamics2DEngine().GetElevation());
    GetBoundingBox().MaxCorner.SetX(tBoundingBox.r);
    GetBoundingBox().MaxCorner.SetY(tBoundingBox.t);
    GetBoundingBox().MaxCorner.SetZ(GetDynamics2DEngine().GetElevation() + fMaxHeight);
 }
Example #8
0
cpBool Buoyancy::WaterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr)
{
    CP_ARBITER_GET_SHAPES(arb, water, poly);
    cpBody *body = cpShapeGetBody(poly);

    // Get the top of the water sensor bounding box to use as the water level.
    cpFloat level = cpShapeGetBB(water).t;

    // Clip the polygon against the water level
    int count = cpPolyShapeGetCount(poly);
    int clippedCount = 0;
#ifdef _MSC_VER
    // MSVC is pretty much the only compiler in existence that doesn't support variable sized arrays.
    cpVect clipped[10];
#else
    cpVect clipped[count + 1];
#endif

    for(int i=0, j=count-1; i<count; j=i, i++){
        cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, j));
        cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, i));

        if(a.y < level){
            clipped[clippedCount] = a;
            clippedCount++;
        }

        cpFloat a_level = a.y - level;
        cpFloat b_level = b.y - level;

        if(a_level*b_level < 0.0f){
            cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level));

            clipped[clippedCount] = cpvlerp(a, b, t);
            clippedCount++;
        }
    }

    // Calculate buoyancy from the clipped polygon area
    cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped, 0.0f);
    cpFloat displacedMass = clippedArea*FLUID_DENSITY;
    cpVect centroid = cpCentroidForPoly(clippedCount, clipped);

    cpDataPointer data = ptr;
    DrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f), data);
    DrawDot(5, centroid, RGBAColor(0, 0, 1, 1), data);

    cpFloat dt = cpSpaceGetCurrentTimeStep(space);
    cpVect g = cpSpaceGetGravity(space);

    // Apply the buoyancy force as an impulse.
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(g, -displacedMass*dt), centroid);

    // Apply linear damping for the fluid drag.
    cpVect v_centroid = cpBodyGetVelocityAtWorldPoint(body, centroid);
    cpFloat k = k_scalar_body(body, centroid, cpvnormalize(v_centroid));
    cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY;
    cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag
    //	cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), centroid);

    // Apply angular damping for the fluid drag.
    cpVect cog = cpBodyLocalToWorld(body, cpBodyGetCenterOfGravity(body));
    cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(cog), 0.0f);
    cpBodySetAngularVelocity(body, cpBodyGetAngularVelocity(body)*cpfexp(-w_damping*dt/cpBodyGetMoment(body)));

    return cpTrue;
}