Exemple #1
0
void *
cpHashSetInsert(cpHashSet *set, unsigned int hash, void *ptr, void *data)
{
	int index = hash%set->size;
	
	// Find the bin with the matching element.
	cpHashSetBin *bin = set->table[index];
	while(bin && !set->eql(ptr, bin->elt))
		bin = bin->next;
	
	// Create it necessary.
	if(!bin){
		bin = (cpHashSetBin *)cpmalloc(sizeof(cpHashSetBin));
		bin->hash = hash;
		bin->elt = set->trans(ptr, data); // Transform the pointer.
		
		bin->next = set->table[index];
		set->table[index] = bin;
		
		set->entries++;
		
		// Resize the set if it's full.
		if(setIsFull(set))
			cpHashSetResize(set);
	}
	
	return bin->elt;
}
Exemple #2
0
static cpContactBufferHeader *
cpSpaceAllocContactBuffer(cpSpace *space)
{
	cpContactBuffer *buffer = (cpContactBuffer *)cpmalloc(sizeof(cpContactBuffer));
	cpArrayPush(space->allocatedBuffers, buffer);
	return (cpContactBufferHeader *)buffer;
}
Exemple #3
0
// Transformation function for collFuncSet.
static void *
collFuncSetTrans(cpCollisionHandler *handler, void *unused)
{
	cpCollisionHandler *copy = (cpCollisionHandler *)cpmalloc(sizeof(cpCollisionHandler));
	(*copy) = (*handler);
	
	return copy;
}
Exemple #4
0
static void *
postStepFuncSetTrans(postStepCallback *callback, void *ignored)
{
	postStepCallback *value = (postStepCallback *)cpmalloc(sizeof(postStepCallback));
	(*value) = (*callback);
	
	return value;
}
Exemple #5
0
cpArray*
cpArrayInit(cpArray *arr, int size)
{
	arr->num = 0;
	
	size = (size ? size : 4);
	arr->max = size;
	arr->arr = (void **)cpmalloc(size*sizeof(void**));
	
	return arr;
}
Exemple #6
0
// Get a recycled or new bin.
static inline cpSpaceHashBin *
getEmptyBin(cpSpaceHash *hash)
{
	cpSpaceHashBin *bin = hash->bins;
	
	// Make a new one if necessary.
	if(bin == NULL) return (cpSpaceHashBin *)cpmalloc(sizeof(cpSpaceHashBin));

	hash->bins = bin->next;
	return bin;
}
Exemple #7
0
// Collide circles to segment shapes.
static int
circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con)
{
	cpCircleShape *circ = (cpCircleShape *)circleShape;
	cpSegmentShape *seg = (cpSegmentShape *)segmentShape;
	
	// Radius sum
	cpFloat rsum = circ->r + seg->r;
	
	// Calculate normal distance from segment.
	cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);
	cpFloat dist = cpfabs(dn) - rsum;
	if(dist > 0.0f) return 0;
	
	// Calculate tangential distance along segment.
	cpFloat dt = -cpvcross(seg->tn, circ->tc);
	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);
	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);
	
	// Decision tree to decide which feature of the segment to collide with.
	if(dt < dtMin){
		if(dt < (dtMin - rsum)){
			return 0;
		} else {
			return circle2circleQuery(circ->tc, seg->ta, circ->r, seg->r, con);
		}
	} else {
		if(dt < dtMax){
			cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);
			(*con) = (cpContact *)cpmalloc(sizeof(cpContact));
			cpContactInit(
				(*con),
				cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),
				n,
				dist,
				0				 
			);
			return 1;
		} else {
			if(dt < (dtMax + rsum)) {
				return circle2circleQuery(circ->tc, seg->tb, circ->r, seg->r, con);
			} else {
				return 0;
			}
		}
	}
	
	return 1;
}
Exemple #8
0
// Transformation function for contactSet.
static void *
contactSetTrans(cpShape **shapes, cpSpace *space)
{
	if(space->pooledArbiters->num == 0){
		// arbiter pool is exhausted, make more
		int count = CP_BUFFER_BYTES/sizeof(cpArbiter);
		cpAssert(count, "Buffer size too small.");
		
		cpArbiter *buffer = (cpArbiter *)cpmalloc(CP_BUFFER_BYTES);
		cpArrayPush(space->allocatedBuffers, buffer);
		
		for(int i=0; i<count; i++) cpArrayPush(space->pooledArbiters, buffer + i);
	}
	
	return cpArbiterInit((cpArbiter *) cpArrayPop(space->pooledArbiters), shapes[0], shapes[1]);
}
Exemple #9
0
// This one is less gross, but still gross.
// TODO: Comment me!
static int
circle2poly(cpShape *shape1, cpShape *shape2, cpContact **con)
{
	cpCircleShape *circ = (cpCircleShape *)shape1;
	cpPolyShape *poly = (cpPolyShape *)shape2;
	cpPolyShapeAxis *axes = poly->tAxes;
	
	int mini = 0;
	cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;
	for(int i=0; i<poly->numVerts; i++){
		cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;
		if(dist > 0.0f){
			return 0;
		} else if(dist > min) {
			min = dist;
			mini = i;
		}
	}
	
	cpVect n = axes[mini].n;
	cpVect a = poly->tVerts[mini];
	cpVect b = poly->tVerts[(mini + 1)%poly->numVerts];
	cpFloat dta = cpvcross(n, a);
	cpFloat dtb = cpvcross(n, b);
	cpFloat dt = cpvcross(n, circ->tc);
		
	if(dt < dtb){
		return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);
	} else if(dt < dta) {
		(*con) = (cpContact *)cpmalloc(sizeof(cpContact));
		cpContactInit(
			(*con),
			cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),
			cpvneg(n),
			min,
			0				 
		);
	
		return 1;
	} else {
		return circle2circleQuery(circ->tc, a, circ->r, 0.0f, con);
	}
}
Exemple #10
0
// Helper function for allocating contact point lists.
static cpContact *
addContactPoint(cpContact **arr, int *max, int *num)
{
	if(*arr == NULL){
		// Allocate the array if it hasn't been done.
		(*max) = 2;
		(*num) = 0;
		(*arr) = (cpContact *)cpmalloc((*max)*sizeof(cpContact));
	} else if(*num == *max){
		// Extend it if necessary.
		(*max) *= 2;
		(*arr) = (cpContact *)cprealloc(*arr, (*max)*sizeof(cpContact));
	}
	
	cpContact *con = &(*arr)[*num];
	(*num)++;
	
	return con;
}
// Transformation function for the handleset.
static void *
handleSetTrans(void *obj, cpSpaceHash *hash)
{
	if(hash->pooledHandles->num == 0){
		// handle pool is exhausted, make more
		int count = CP_BUFFER_BYTES/sizeof(cpHandle);
		cpAssert(count, "Buffer size is too small.");
		
		cpHandle *buffer = (cpHandle *)cpmalloc(CP_BUFFER_BYTES);
		cpArrayPush(hash->allocatedBuffers, buffer);
		
		for(int i=0; i<count; i++) cpArrayPush(hash->pooledHandles, buffer + i);
	}
	
	cpHandle *hand = cpHandleInit((cpHandle *) cpArrayPop(hash->pooledHandles), obj);
	cpHandleRetain(hand);
	
	return hand;
}
// Get a recycled or new bin.
static inline cpSpaceHashBin *
getEmptyBin(cpSpaceHash *hash)
{
	cpSpaceHashBin *bin = hash->pooledBins;
	
	if(bin){
		hash->pooledBins = bin->next;
		return bin;
	} else {
		// Pool is exhausted, make more
		int count = CP_BUFFER_BYTES/sizeof(cpSpaceHashBin);
		cpAssert(count, "Buffer size is too small.");
		
		cpSpaceHashBin *buffer = (cpSpaceHashBin *)cpmalloc(CP_BUFFER_BYTES);
		cpArrayPush(hash->allocatedBuffers, buffer);
		
		// push all but the first one, return the first instead
		for(int i=1; i<count; i++) recycleBin(hash, buffer + i);
		return buffer;
	}
}
Exemple #13
0
static cpHashSetBin *
getUnusedBin(cpHashSet *set)
{
    int i;
	cpHashSetBin *bin = set->pooledBins;
	
	if(bin){
		set->pooledBins = bin->next;
		return bin;
	} else {
		// Pool is exhausted, make more
		int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);
		cpAssert(count, "Buffer size is too small.");
		
		cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
		cpArrayPush(set->allocatedBuffers, buffer);
		
		// push all but the first one, return the first instead
		for(i=1; i<count; i++) recycleBin(set, buffer + i);
		return buffer;
	}
}
Exemple #14
0
// Add contact points for circle to circle collisions.
// Used by several collision tests.
static int
circle2circleQuery(cpVect p1, cpVect p2, cpFloat r1, cpFloat r2, cpContact **con)
{
	cpFloat mindist = r1 + r2;
	cpVect delta = cpvsub(p2, p1);
	cpFloat distsq = cpvlengthsq(delta);
	if(distsq >= mindist*mindist) return 0;
	
	cpFloat dist = cpfsqrt(distsq);
	// To avoid singularities, do nothing in the case of dist = 0.
	cpFloat non_zero_dist = (dist ? dist : INFINITY);

	// Allocate and initialize the contact.
	(*con) = (cpContact *)cpmalloc(sizeof(cpContact));
	cpContactInit(
		(*con),
		cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/non_zero_dist)),
		cpvmult(delta, 1.0f/non_zero_dist),
		dist - mindist,
		0
	);
	
	return 1;
}
Exemple #15
0
cpBody*
cpBodyAlloc(void)
{
	return (cpBody *)cpmalloc(sizeof(cpBody));
}
Exemple #16
0
cpSimpleMotor *
cpSimpleMotorAlloc(void)
{
	return (cpSimpleMotor *)cpmalloc(sizeof(cpSimpleMotor));
}
Exemple #17
0
static cpHandle*
cpHandleAlloc(void)
{
	return (cpHandle *)cpmalloc(sizeof(cpHandle));
}
cpRotaryLimitJoint *
cpRotaryLimitJointAlloc(void)
{
	return (cpRotaryLimitJoint *)cpmalloc(sizeof(cpRotaryLimitJoint));
}
Exemple #19
0
cpPulleyJoint *
cpPulleyJointAlloc(void)
{
	return (cpPulleyJoint *)cpmalloc(sizeof(cpPulleyJoint));	
}
Exemple #20
0
cpGearJoint *
cpGearJointAlloc(void)
{
	return (cpGearJoint *)cpmalloc(sizeof(cpGearJoint));
}
Exemple #21
0
cpSlideJoint *
cpSlideJointAlloc(void)
{
	return (cpSlideJoint *)cpmalloc(sizeof(cpSlideJoint));
}
cpRatchetJoint *
cpRatchetJointAlloc(void)
{
	return (cpRatchetJoint *)cpmalloc(sizeof(cpRatchetJoint));
}
cpPivotJoint *
cpPivotJointAlloc(void)
{
	return (cpPivotJoint *)cpmalloc(sizeof(cpPivotJoint));
}
Exemple #24
0
cpGrooveJoint *
cpGrooveJointAlloc(void)
{
	return (cpGrooveJoint *)cpmalloc(sizeof(cpGrooveJoint));
}
cpDampedRotarySpring *
cpDampedRotarySpringAlloc(void)
{
	return (cpDampedRotarySpring *)cpmalloc(sizeof(cpDampedRotarySpring));
}
cpOscillatingMotor *
cpOscillatingMotorAlloc(void)
{
	return (cpOscillatingMotor *)cpmalloc(sizeof(cpOscillatingMotor));
}