Class membership of Ray-AABB intersection function - c++

I'm writing code for mouse picking in 3D space. So far I've made Ray and AABB classes. What I need is a function for Ray-AABB intersecting. I know how to write it and make it work, my question is which class should define said funcion? Should it be a member of Ray or AABB, both, neither? What are the best practices for object oriented approach?
For me it makes the most sense to implement that function as a member of "engine" class, more like a procedure rather than a function. However I want my code to be truly object oriented.

I would say: neither.
Ray: Structure (Members: Start, End)
AABB: Structure (Members: Position, Size).
Ray-AABB intersection method could be in a Physics or Intersection class (Depends on your actual context) as static methods (Or functions in a namespace, depends on your coding convention).
Object oriented is fine, but it doesn't mean that everything you create should be a class.
Data oriented is a very good approach (CPU friendly with less cache misses).
EDIT: A good coding rule is to think your things independently, meaning that the AABB implementation shouldn't be dependent on the Ray implementation.

Related

Making a simple particle system

I had a question regarding the way I am designing my particle system.
Right now I have a class P, which stores all the information about a particle such as speed, position, direction, type, etc. I also have a main file I will be drawing these particles, updating and instantiating them in. I want to create a list of these particles using the c++ std list library, so initially I did
std::list<P> listOfParticles;
in the main file. Here is the problem. By doing this I will essentially be forced to make my update and draw functions in the main file. I feel like this is bad practice, and that everything to do with the particle should be kept in one class, but I am unsure where to go from here in terms of best practice. Would it be a good idea to just create a list of particles in the class P where I am defining what a particle is? I feel like this isn't a smart idea though..
If anyone could guide me in the right direction I would really appreciate it.
"By doing this I will essentially be forced to make my update and draw functions in the main file"
No one is stopping you from putting declarations/definitions of class members in same/different .h/.cpp files.
EDIT:-
That's what I said, better it would be if you make this List a member of some other class where you would put all functions to manipulate this list.
Your list of particles most probably deserves its own class, let C, that will handle storage, initial spatial distribution, temporal updates... i.e. all global operations on the particle cloud. If you are sure that you will ever handle a single list, you can make it a static member.
The class that represents the individual particles (P) can be nested into (C) if there is no need to see it from outside. It will encapsulate particle data and possibly also model pairwise interaction with another particle and other single-particle operations.

Using dynamic_cast for collision detection in a 2D environment

I'm developing a base for a 2D game. My general design is something like this:
class Entity:
Every object class (like a wall, an enemy, floor etc.) derives
from this class. Most of the functions are pure virtual. There is
a hitbox as well.
class Scene:
Contains pointers to Entity-objects. When an Entity-pointer is added,
it will be given a Scene-pointer to its parent so it may access that.
Scene also has a collision-detecting function:
getIntersections<T> (Entity *)
getIntersections<T...> (Entity *)
(both return a std::vector<Entity *>)
This basically gets all Entity *s intersecting the parameter-Entity * (by checking the hitbox) and then tries to dynamic_cast<T *> them. All matching Entity *s (not the casted ones) are then returned. The variadic template is used for checking for more then one intersecting class.
My basic idea behind that was, if I had a Player-class (which represents the player obviously), and some other classes like Enemy, Wall, etc., it would be an easy task to check if a Player-object was colliding with one(or more) of these:
// (inside Player::tick(); quick and dirty)
{
if ( (this->parentScene->getIntersections<Wall>(this)).empty() )
// player does not collide with a wall, just move.
else
// player does collide with a wall, do whatever.
}
However, I have got two questions on that:
Does my (general) design show up flaws for the need of dynamic_cast<T *> as replacement for instanceof (like there is in Java for example)
Is it a performant solution on the task? Since for every collision check, Scene basically loops through every Entity * it contains, checks if it collides with the given Entity * and finally casts it to check if it derives from another given class. If that is not performant, what changes were to make in my design to make it performant?
On the performance part it would be better to separate entities in separate vectors by primitive type. Not only you can specifically test a plane vs a sphere for example it eliminates the need to have dynamic_cast entirely ( -> extra speedup ). Also since you already separated the types in vectors you can just ignore the virtual functions and go for non virtual call providing additional performance improvement;
So your scene would look something like this:
class scene
{
std::vector<PlaneEntity> m_planes;
std::vector<CircleEntity> m_circles;
};
And regarding the design of this it is much easier to select the right algorithm when intersecting primities:
This is an example on how a basic collision checking would look based on this design:
void colide(const PlaneEntity & e)
{
for each plane
call plane vs plane collision
for each circle
call plane vs circle collision;
};
void colide(const CircleEntity & e)
{
for each plane
call plane vs circle collision;
for each circle
call circle vs circle collision;
};
So to answer your question:
1: it is not a rule weather to use or not dynamic_cast, it is known that not using it is better for performance.
2: The design described above is not performant at all. Also your design with dynamic cast is even slower. To improve this you need to look into accelerations structures (this is huge topic so i can't explaing everything here) to speed up collision detection. They basically reduce the number of collision check for each primitive giving a massive improvement in performance. Basic structures are KD-Tree, Quad-Trees, Spacial-Hash , Grid, etc. You can find lots of code for each just by googleing them.
Hope this helps,
Raxvan.

C++ Composition - must I wrap all those functions?

I've got a C++ class that describes an object's orientation in 3D space - location, rotation, scale, etc. I have other classes that necessarily need information like that (or a subset of it) - models, terrains, cameras, etc. Now I could make those subclasses of my orientation class, but the Googles have told me to prefer composition over inheritance. This philosophically makes sense - a model is not an orientation, it has one (and yes I know the is-a has-a thing is just a heuristic). Yet it seems needlessly, almost comically inelegant to rewrite the same wrapper methods for all those would-be subclasses just go get at that functionality. Things like model.getOrientation().set_x(1) seem silly as well.
I can see why this wouldn't be "too bad" for small objects, but for this example (and others like it), what's the point of composition if you have to go through hoops anyway to pretend that you're using inheritance? Should I even use it now? I'm almost certain I'm thinking about this improperly.
There's a cheap way to avoid most of the wrapping boilerplate.
class model : private orientation {
public:
using orientation::set_x;
... etc ...
};
Private inheritance in C++ doesn't (necessarily) mean "is a". It's more-or-less invisible to outsiders, and is sometimes described as meaning "is implemented in terms of a". That is, you get a limited form of composition that helpfully gives you the ability to expose part or all of the interface of the composed object.
It may seem silly but your model.getOrientation().set_x(1) is probably the way to go.
If you get tired of typing the getOrientation() part, you could try something like this:
Orientation & orient = model.getOrientation();
orient.set_x(1);
orient.set_y(1);
if( orient.check_something() ) {
//whatever
}
//etc.
Write a class for things that have an orientation. Let models, terrains, cameras etc. inherit from that class. If you want to do any wrapping, you need to do it in one class only. Using getters is done so that you can change the way the the orientation is stored in the object.

Inheritance/interface decisions for physics engine

This is for a small game project with SDL on MinGW/Windows.
I am working on a physics engine, and my idea was to have a Physics::Object, which all physical objects should derive from and it registers itself with a global Physics::System class (it's a monostate pattern) so that the user doesn't need to track which objects are included in physics calculations and just needs to call a function like Physics::System::PerformTimestepCalculation(double dt).
This works fine, and I even implemented it using a single derived class Physics::Circle, which is a 2d circle. I was pretty happy with the predictive collision detection, even though I still need to optimise it.
Anyway, I ran into trouble when I started adding other primitives to include in the calculation, e.g. line. The Physics::System::PerformTimestepCalculation(double dt) became littered with calls to Object::GetID() or similar functions (may way to avoid dynamic_cast<>), but I feel dirty.
I did a bit of reading and realised that my the elements of my hierarchy are not substitutable (i.e. the collision between two circles is very different between the collision of two lines).
I like the way my Physics::Objects "self register" with the System class so they automatically get included in the calculations, and I don't really want to lose this.
There must be some other sensible design paths. How can I better redesign things so non-substitutable objects do not get in the way?
Edit FYI:
In the end I have broken away entity and shape properties, similar to how it was described in the accepted answer, and similar to an entity-component-system model. It means I still have the yuk logic of "is this a circle or a line, and is that a line or a circle?", but I'm no longer pretending that polymorphism helps me here. It also means I use some sort of factory and can have multiple calculation worlds happening at once!
The most successful publically available physics engines are not very heavy on the 'patterns' or 'object oriented design'.
Here's a rundown to back up my, admittedly bold, assertion:
Chipmunk - written in C, enough said.
Box2d - Written in C++, and there is some polymorphism here. there's a hierarchy of shapes (base class b2Shape) with a few virtual function. That abstraction leaks like a sieve, though, and you'll find lots of casts to leaf classes throughout the source code. There's also a hierarchy of 'contacts', which proves more successful, although with a single virtual function it would be trivial to rewrite this without polymorphism (chipmunk uses a function pointer, I believe). b2Body is the class used to represent rigid bodies, and it is non-virtual.
Bullet - Written in C++, used in a ton of games. Tons of features, tons of code (relative to the other two). There's actually a base class that the rigid body and soft body representations extend, but only a small part of the code can make any use of it. Most of the base class's virtual function relate to serialization (save/load of the engine state), of the two remaining virtual functions soft body fails to implement one with a TODO informing us that some hack needs to be cleaned up. Not exactly a ringing endorsement of polymorphism in physics engines.
That's a lot of words, and I haven't even really started answering your question. All I want to hammer home is that polymorphism is not something that is applied effectively in existing physics engines. And that's probably not because the authors didn't "get" OO.
So anyway, my advice: ditch polymorphism for your entity class. You're not going to end up with 100 different types that you can't possibly refactor at a later date, your physics engine's shape data will be fairly homogeneous (convex polys, boxes, spheres, etc) and your entity data will likely be even more homogeneous (probably just rigid bodies to start with).
Another mistake that I feel you're making is only supporting one Physics::System. There is utility in being able to simulate bodies independently of eachother (for instance, for a two player game), and the easiest way to do this is to support multiple Physics::Systems.
With that in mind, the cleanest 'pattern' to follow would be a factory pattern. When users want to create a rigid body, they need to tell the Physics::System (acting as a factory) to do it for them, so in your Physics::System:
// returning a smart pointer would not be unreasonable, but I'm returning a raw pointer for simplicity:
rigid_body_t* AddBody( body_params_t const& body_params );
And in the client code:
circle_params_t circle(1.f /*radius*/);
body_params_t b( 1.f /*mass*/, &circle /*shape params*/, xform /*system transform*/ );
rigid_body_t* body = physics_system.AddBody( b );
Anyhoo, kind of a rant. Hope this is helpful. At the very least I want to point you towards box2d. It's written in a pretty simple dialect of C++ and the patterns applied therein will be relevant to your engine, whether it's 3D or 2D.
The problem of hierarchies is that they don't always make sense, and trying to cram everything into a hierarchy just results in awkward decisions and frustrating work down the line.
The other solution that can be used is the tagged union one, best embodied by boost::variant.
The idea is to create an object that can hold one instance of a given type (among a preselected list) at any given time:
typedef boost::variant<Ellipsis, Polygon, Blob> Shape;
And then you can provide the functionality by switching over the type list:
struct AreaComputer: boost::static_visitor<double> {
template <typename T>
double operator()(T const& e) { return area(a); }
};
void area(Shape const& s) {
AreaComputer ac;
return boost::apply_visitor(s, ac);
}
The performance is the same as a virtual dispatch (so not too much, normally), but you get greater flexibility:
void func(boost::variant<Ellipsis, Blob> const& eb);
void bar(boost::variant<Ellipsis, Polygon> const& ep);
// ...
You can provide functions only when relevant.
And on the subject of binary visitation:
struct CollisionComputer: boost::static_visitor<CollisionResult> {
CollisionResult operator()(Circle const& left, Circle const& right);
CollisionResult operator()(Line const& left, Line const& right);
CollisionResult operator()(Circle const& left, Line const& right);
CollisionResult operator()(Line const& left, Circle const& right);
};
CollisionResult collide(Shape const& left, Shape const& right) {
return boost::apply_visitor(CollisionComputer(), left, right);
}

How to restructure this code hierarchy (relating to the Law of Demeter)

I've got a game engine where I'm splitting off the physics simulation from the game object functionality. So I've got a pure virtual class for a physical body
class Body
from which I'll be deriving various implementations of a physics simulation. My game object class then looks like
class GameObject {
public:
// ...
private:
Body *m_pBody;
};
and I can plug in whatever implementation I need for that particular game. But I may need access to all of the Body functions when I've only got a GameObject. So I've found myself writing tons of things like
Vector GameObject::GetPosition() const { return m_pBody->GetPosition(); }
I'm tempted to scratch all of them and just do stuff like
pObject->GetBody()->GetPosition();
but this seems wrong (i.e. violates the Law of Demeter). Plus, it simply pushes the verbosity from the implementation to the usage. So I'm looking for a different way of doing this.
The idea of the law of Demeter is that your GameObject isn't supposed to have functions like GetPosition(). Instead it's supposed to have MoveForward(int) or TurnLeft() functions that may call GetPosition() (along with other functions) internally. Essentially they translate one interface into another.
If your logic requires a GetPosition() function, then it makes sense turn that into an interface a la Ates Goral. Otherwise you'll need to rethink why you're grabbing so deeply into an object to call methods on its subobjects.
One approach you could take is to split the Body interface into multiple interfaces, each with a different purpose and give GameObject ownership of only the interfaces that it would have to expose.
class Positionable;
class Movable;
class Collidable;
//etc.
The concrete Body implementations would probably implement all interfaces but a GameObject that only needs to expose its position would only reference (through dependency injection) a Positionable interface:
class BodyA : public Positionable, Movable, Collidable {
// ...
};
class GameObjectA {
private:
Positionable *m_p;
public:
GameObjectA(Positionable *p) { m_p = p; }
Positionable *getPosition() { return m_p; }
};
BodyA bodyA;
GameObjectA objA(&bodyA);
objA->getPosition()->getX();
Game hierarchies should not involve a lot of inheritance. I can't point you to any web pages, but that is the feeling I've gather from the several sources, most notably the game gem series.
You can have hierarchies like ship->tie_fighter, ship->x_wing. But not PlaysSound->tie_fighter. Your tie_fighter class should be composed of the objects it needs to represent itself. A physics part, a graphics part, etc. You should provide a minimal interface for interacting with your game objects. Implement as much physics logic in the engine or in the physic piece.
With this approach your game objects become collections of more basic game components.
All that said, you will want to be able to set a game objects physical state during game events. So you'll end up with problem you described for setting the various pieces of state. It's just icky but that is best solution I've found so far.
I've recently tried to make higher level state functions, using ideas from Box2D. Have a function SetXForm for setting positions etc. Another for SetDXForm for velocities and angular velocity. These functions take proxy objects as parameters that represent the various parts of the physical state. Using methods like these you could reduce the number of methods you'd need to set state but in the end you'd probably still end up implementing the finer grained ones, and the proxy objects would be more work than you would save by skipping out on a few methods.
So, I didn't help that much. This was more a rebuttal of the previous answer.
In summary, I would recommend you stick with the many method approach. There may not always be a simple one to 1 relationship between game objects and physic objects. We ran into that where it was much simpler to have one game object represent all of the particles from an explosion. If we had given in and just exposed a body pointer, we would not have been able to simplify the problem.
Do I understand correctly that you're separating the physics of something from it's game representation?
i.e, would you see something like this:
class CompanionCube
{
private:
Body* m_pPhysicsBody;
};
?
If so, that smells wrong to me. Technically your 'GameObject' is a physics object, so it should derive from Body.
It sounds like you're planning on swapping physics models around and that's why you're attempting to do it via aggregation, and if that's the case, I'd ask: "Do you plan on swapping physics types at runtime, or compile time?".
If compile time is your answer, I'd derive your game objects from Body, and make Body a typedef to whichever physics body you want to have be the default.
If it's runtime, you'd have to write a 'Body' class that does that switching internally, which might not be a bad idea if your goal is to play around with different physics.
Alternatively, you'll probably find you'll have different 'parent' classes for Body depending on the type of game object (water, rigid body, etc), so you could just make that explicit in your derivation.
Anyhow, I'll stop rambling since this answer is based on a lot of guesswork. ;) Let me know if I'm off base, and I'll delete my answer.