Resolving collisions with enums

Started by
1 comment, last by Krohm 8 years, 2 months ago

Hey all, just looking for some suggestions on how to resolve collisions in my game engine.

Here's what I'm working with:

I have a spatial partition of GameObjects, where I do my collision detection. If a collision is detected, A Resolution object is returned with the following format:

struct Resolution{

unsigned int colBoxA; //Index of collision box within object

unsigned int colBoxB;

//One or two trival members not important here

};

1. I iterate through all the Partition buckets to test for collisions.

2. I have a Map container which stores all the Resolution objects. To ensure each collision is unique they key for the map is

a pair of both GameObject_ID's, and the value is the Resolution object.

3. colBoxA and colBoxB are indices to AABB's that reside in each object. Let's say ObjectA has two collision boxes: A hitbox and a shield, while ObjectB has a single collision box: a projectile. So an entry in my Resolution container has information on which two objects are colliding, and on which respective collisionbox.

4. Each Collisionbox has an enumerated type associated with it (Wall,projectile,hitbox,melee) etc.....

I want to resolve the collision based on both the types associated with the collision, and apply the result correctly to each object. I've looked around, and it seems like I should be using some type of Strategy Pattern. By not using this, it looks like I am facing nested switches (not going to happen). Even with the Strategy Pattern, I am unsure on how to implement this.

Any advice or similar documentation would be greatly appreciated :)

Advertisement

Hey all, just looking for some suggestions on how to resolve collisions in my game engine.

Here's what I'm working with:

I have a spatial partition of GameObjects, where I do my collision detection. If a collision is detected, A Resolution object is returned with the following format:

struct Resolution{

unsigned int colBoxA; //Index of collision box within object

unsigned int colBoxB;

//One or two trival members not important here

};

1. I iterate through all the Partition buckets to test for collisions.

2. I have a Map container which stores all the Resolution objects. To ensure each collision is unique they key for the map is

a pair of both GameObject_ID's, and the value is the Resolution object.

3. colBoxA and colBoxB are indices to AABB's that reside in each object. Let's say ObjectA has two collision boxes: A hitbox and a shield, while ObjectB has a single collision box: a projectile. So an entry in my Resolution container has information on which two objects are colliding, and on which respective collisionbox.

4. Each Collisionbox has an enumerated type associated with it (Wall,projectile,hitbox,melee) etc.....

I want to resolve the collision based on both the types associated with the collision, and apply the result correctly to each object. I've looked around, and it seems like I should be using some type of Strategy Pattern. By not using this, it looks like I am facing nested switches (not going to happen). Even with the Strategy Pattern, I am unsure on how to implement this.

Any advice or similar documentation would be greatly appreciated smile.png

A simple solution would be to use a 2d array for the collision type. This can be a const fixed array or a dynamic array created on the game initialization process. This would look like this (I use this for my contact generators - copied from my java source):


public final class ContactGeneratorFactory {
	private final int MAX_GENERATORS_PER_SHAPE = ShapeType.COUNT.id;
	private final ContactGenerator[][] generators = new ContactGenerator[MAX_GENERATORS_PER_SHAPE][MAX_GENERATORS_PER_SHAPE];
	
	public ContactGeneratorFactory() {
		generators[ShapeType.Plane.id][ShapeType.Circle.id] = new PlaneCircleContactGenerator();
		generators[ShapeType.Plane.id][ShapeType.Box.id] = new PlaneEdgeContactGenerator();
		generators[ShapeType.Plane.id][ShapeType.Polygon.id] = new PlaneEdgeContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Box.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.LineSegment.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Box.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Box.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Polygon.id][ShapeType.Circle.id] = new EdgeCircleContactGenerator();
		generators[ShapeType.Polygon.id][ShapeType.Polygon.id] = new EdgeEdgeContactGenerator();
		generators[ShapeType.Circle.id][ShapeType.Circle.id] = new CircleCircleContactGenerator();
	}
	
	public int generate(Transform transformA, Transform transformB, Shape shapeA, Shape shapeB, int offset, Contact[] contacts, ContactAcceptor acceptor) {
		int result = 0;
		
		// Sort shape types
		boolean flip = false;
		ShapeType typeA = shapeA.type;
		ShapeType typeB = shapeB.type;
		if (typeA.id > typeB.id) {
			ShapeType temp = typeA;
			typeA = typeB;
			typeB = temp;
			flip = true;
		}
		
		// Find generator by both shape type id´s
		ContactGenerator generator = generators[typeA.id][typeB.id];
		if (generator != null) {
			// do something with the found generator
		}
	}
}

You just create classes based on some simple CollisionResponse interface and create instances for every possible pairs.

Important: The order of your object collision enumeration matters, see:


public enum ShapeType {
	Plane(1),
	LineSegment(2),
	Box(3),
	Polygon(4),
	Circle(5),
	COUNT(6);
	
	public final int id;
	
	private ShapeType(int id) {
		this.id = id;
	}
}


I want to resolve the collision based on both the types associated with the collision, and apply the result correctly to each object. I've looked around, and it seems like I should be using some type of Strategy Pattern. By not using this, it looks like I am facing nested switches (not going to happen). Even with the Strategy Pattern, I am unsure on how to implement this.
I would like to see those solutions you have found... Bullet (industry-wide used rigid body dynamics API) just allocates one bit for each group of collision-able types and then masks the two things together. Using bitmasks is of course inconvenient but you can abstract them a bit. I recall the filtering routines being fairly simple, maybe you can take a stab at the source code.

Previously "Krohm"

This topic is closed to new replies.

Advertisement