Control flow based on type in C++

Started by
12 comments, last by MarcusAseth 6 years, 6 months ago
Advertisement

Thanks for the wonderful post i learned a lot

Without templates, 



typedef int WorldTransform; //typedef, should be a matrix
typedef int Rect3D;			//should be a 3d-rect, 8 poinits or w/e
typedef int MeshData;		//collection of tri or w/e

class CollisionObject {
public:
	enum class CollisionObjectID { Sphere, Cube, Mesh };

	class CollisionShape {
	public:
		CollisionObjectID mCollisionObjectID;

		CollisionShape(CollisionObjectID id)
			:mCollisionObjectID(id)
		{}
	};

	class Sphere :	public CollisionShape {
	public:
		double mRadius;

		Sphere()
			:CollisionShape(CollisionObjectID::Sphere)
		{}
	};

	class Cube :	public CollisionShape {
	public:
		Rect3D mRect;

		Cube()
			:CollisionShape(CollisionObjectID::Cube)
		{}
	};

	class Mesh :	public CollisionShape {
		MeshData mMeshData;
	
	public:
		Mesh()
			:CollisionShape(CollisionObjectID::Mesh)
		{}
	};

protected:

	CollisionShape* mCollisionShape;
	WorldTransform mWorldTransform;

	//trickle-down comparisons, you need to pass obj1/obj2 to these functions, not implemented, see collidesWith
	bool SphereVsSphere() { return true; }
	bool SphereVsCube() { return true; }
	bool SphereVsMesh() { return true; }

	bool CubeVsCube() { return true; }
	bool CubeVsMesh() { return true; }

	bool MeshVsMesh() { return true; }

public:
	CollisionObject( WorldTransform worldTransform, CollisionShape* shape)
		: mWorldTransform( worldTransform )
		, mCollisionShape( shape )
	{}

	bool collidesWith(CollisionObject* obj2) {

		//ensure that the trickle down functions work by ordering objs 1 < 2
		CollisionObject* obj1 = this;
		if (obj2->mCollisionShape->mCollisionObjectID < mCollisionShape->mCollisionObjectID)
			std::swap(obj1, obj2);

		CollisionObjectID id1= obj1->mCollisionShape->mCollisionObjectID, id2 = obj2->mCollisionShape->mCollisionObjectID;

		switch ( id1 ){
		case CollisionObjectID::Sphere:

			switch( id2 ) {
			case CollisionObjectID::Sphere:
				SphereVsSphere();
				break;
			case CollisionObjectID::Cube:
				SphereVsCube();
				break;
			case CollisionObjectID::Mesh:
				SphereVsMesh();
				break;
			}
			break;

		case CollisionObjectID::Cube:

			switch ( id2 ) {
			case CollisionObjectID::Cube:
				CubeVsCube();
				break;
			case CollisionObjectID::Mesh:
				CubeVsMesh();
				break;
			}
			break;

		case CollisionObjectID::Mesh:
			MeshVsMesh();
			break;
		}
	}
};

class PhysicalObject {
protected:
	std::vector< CollisionObject > mCollisionObjects;
public:

	bool collidesWith(PhysicalObject* obj2) {

		for (auto child1 : mCollisionObjects) {
			for( auto child2 : obj2->mCollisionObjects )
				if (child1.collidesWith( &child2 )) return true;
		}
		return false;
	}
};

class Paddle : public PhysicalObject {

	CollisionObject::Cube mCollisionShapeCube; // can also store all shapes in a repository and have a ptr here
public:
	Paddle() {
		//can push back as many objects as want, worm could have several cubes or spheres or w/e
		mCollisionObjects.push_back(CollisionObject(WorldTransform(), &mCollisionShapeCube));
	}
};

You'd run down all physical objects that potentially intersect, and call colldiesWith. In a game like breakout I don't think you'd have enough objects to worry about comparing to all of them.

Sorry if I'm not answering to this topic for a while guys, I dont want you get the wrong idea that I am not interested or something, is just that I've paused my project few days ago because I am getting lost and I need to do more reading (of basic stuff as well) in order to be able to proceed, so currently I am going trough some books and online material, but I'll be back and resume this and read again the whole topic once I am done and ready to proceed :)  Thanks for all the answers, which apparently are helping other people as well :) 

 

This topic is closed to new replies.

Advertisement