mosra / magnum

Lightweight and modular C++11 graphics middleware for games and data visualization
https://magnum.graphics/
Other
4.76k stars 438 forks source link

Collision shapes rework #8

Closed mosra closed 11 years ago

mosra commented 11 years ago

Why?

Physics::Point2D a;
Physics::Sphere2D b;
auto shape = new Physics::ObjectShape<Physics::ShapeGroup2D>(o, a || b, shapes);

The above code is not intuitive, becasuse the user might not immediately know that result of a || b is ShapeGroup. Even if he would, this is a lot of unnecessary typing, because the shape type is known from the arguments (unlike in above examples). Two considered (but unsufficient) solutions:

The user can't intuitively tell what's the difference between ObjectShapeGroup and ShapeGroup, thus they should be renamed to something more meaningful. Also why not to move everything to different namespace so Physics can be saved for other things like rigid bodies and particle systems? Linking Physics library just because one needs to click menus seems like overkill. But on the other hand, will collision detection be large enough to be in separate library?

JanDupal commented 11 years ago

From user's point of view I'd appreciate more solution 1.1. I find differentiating between general shapes and physics shapes bit confusing. Ideally user should be able to pass general shape and let framework decide (at compile time) whether it is related to debug drawing, collision detection, physics computation etc. depending on context. But I have no idea about implementation.

Could you please describe issue with ShapeGroup in 1.1?

JanDupal commented 11 years ago

Thoughts:

  1. Algebraic structure like Monoids for shapes
    • encapsulate single shape or shape group
    • provide % and composition operators
    • result: no specific (at least public) type to differentiate "primitive" from "composition of primitives"
    • issues: how to specify position of components in composition
  2. I like the idea with splitting Physics namespace
    • maybe Shapes and Physics
    • Where does "I'd like to render a box!" fit? Is it a primitive or a shape? What about "I'd like to render a box and make it collidable as fast as possible to see if my game idea works."?
mosra commented 11 years ago
  1. this is how it is currently - ShapeGroup which can contain one or more shapes, but the only advantage is the "universal" type, querying the contents is almost impossible. The shapes actually behave like monoids and you have to specify the type only during creation of single shapes, not for the result:

    auto shape = Physics::Point2D({}) || Physics::Sphere2D({3.0f, 1.0f}, 0.5f);

    Nice thing would be to have something like the following to avoid specifying the resulting type altogether to follow the monoids idea, maybe C++17 will be able to do it?:

    new Shapes::Shape<auto>(object, shape);

    Otherwise, to avoid explicit type specification, we must resort to some makeShape() function as described above.

  2. Shapes and Physics, sure.

In current "terminology", primitive is mesh data (vertices, faces, normals...) of some basic object (circle, line, arrow, crosshair, monkey...) to ease up prototyping, shape is (simplified) description of some subspace (which doesn't even need to encapsulate any mesh, e.g. trigger volumes) used for collision detection (primarily not for rendering). User's line of thoughs should be like this:

mosra commented 11 years ago

Done in 06d707f25c517a237d301ae7422309e7a4a81c0e.