diff --git a/include/Collision/collisionMesh.h b/include/Collision/collisionMesh.h index 70e87f24..6407efff 100644 --- a/include/Collision/collisionMesh.h +++ b/include/Collision/collisionMesh.h @@ -20,12 +20,27 @@ namespace Hop::System::Physics using Hop::Object::Component::cTransform; using Hop::Object::Component::cPhysics; + /** + * @brief A point in a collision mesh. + * + */ struct MeshPoint { + /** + * @brief Construct a new Mesh Point from a position and radius. + * + * @param x x coordinate. + * @param y y coordinate. + * @param r radius. + */ MeshPoint(double x, double y, double r) : x(x), y(y), r(r) {} + /** + * @brief Construct a new Mesh Point at (0,0) with radius 0. + * + */ MeshPoint() : x(0.0), y(0.0), r(0.0) {} @@ -40,9 +55,17 @@ namespace Hop::System::Physics } }; + /** + * @brief A rectangular mesh point. + * + */ struct MeshRectangle : public MeshPoint { + /** + * @brief Construct a new Mesh Rectangle with points at 0.0. + * + */ MeshRectangle() : MeshRectangle(0.0, 0.0, 0.0, 0.0, @@ -50,6 +73,18 @@ namespace Hop::System::Physics 0.0, 0.0) {} + /** + * @brief Construct a new Mesh Rectangle from vertices. + * + * @param llx lower left x. + * @param lly lower left y. + * @param ulx upper left x. + * @param uly upper left y. + * @param urx upper right x. + * @param ury upper right y. + * @param lrx lower right x. + * @param lry lower right y. + */ MeshRectangle ( double llx, double lly, @@ -102,16 +137,24 @@ namespace Hop::System::Physics double llx, lly, ulx, uly, urx, ury, lrx, lry; }; + /** + * @brief A mesh of collideable primitives. + * + */ struct CollisionMesh { CollisionMesh() {} - // construct a mesh around a model space polygon - // with vertices v with each mesh vertex having - // radius r in model space - //CollisionMesh(std::vector v, double r = 0.01); - // construct a mesh from given points + /** + * @brief Construct a new Collision Mesh from primitives. + * + * @param v list of collideable primitives. + * @param x x world coordinate of mesh. + * @param y y world coordinate of mesh. + * @param theta orientation of mesh. + * @param scale scale of mesh. + */ CollisionMesh ( std::vector> v, @@ -127,6 +170,11 @@ namespace Hop::System::Physics updateWorldMesh(transform, phys, 0.0); } + /** + * @brief Construct a new Collision Mesh from a primitives list. + * + * @param v list of collideable primitives. + */ CollisionMesh ( std::vector> v @@ -141,6 +189,11 @@ namespace Hop::System::Physics computeRadius(); } + /** + * @brief Construct a new Collision Mesh from another. + * + * @param m the mesh to copy. + */ CollisionMesh ( CollisionMesh & m @@ -161,6 +214,13 @@ namespace Hop::System::Physics someRectangles = m.someRectangles; } + /** + * @brief Construct a new Collision Mesh from model and world vertices. + * + * @param model model positions of mesh primitives. + * @param world world positions of mesh primitives. + * @param tags tags of mesh primitives for sub-meshing. + */ CollisionMesh ( std::vector> model, @@ -177,6 +237,12 @@ namespace Hop::System::Physics updateTags(); } + /** + * @brief Obtain all primitives with the given tag. + * + * @param t tag to select. + * @return (sub) CollisionMesh selected by tag. + */ CollisionMesh getSubMesh(uint64_t t) { auto model = getModelByTag(t); @@ -185,8 +251,17 @@ namespace Hop::System::Physics return CollisionMesh(model, world, tags); } + /** + * @brief Flag mesh as needing an initial update. + * + */ void reinitialise() { needsInit = true; } + /** + * @brief Set the transform of the mesh. + * + * @param t new transform of the mesh. + */ void transform(cTransform t) { needsInit = true; @@ -194,6 +269,11 @@ namespace Hop::System::Physics updateWorldMesh(t, phys, 0.0); } + /** + * @brief Add a primitive to the mesh. + * + * @param c new primitive. + */ void add(std::shared_ptr c) { @@ -279,6 +359,11 @@ namespace Hop::System::Physics needsInit = true; } + /** + * @brief Remove primitive at index i. + * + * @param i index of primitive to remove. + */ void remove(size_t i) { vertices.erase(vertices.begin()+i); @@ -290,6 +375,13 @@ namespace Hop::System::Physics updateTags(); } + /** + * @brief Check if (x,y) hits a primitive. + * + * @param x x coordinate of test point. + * @param y y coordinate of test point. + * @return int index of the first primitive click (or -1 if not clicked). + */ int clicked(float x, float y) { @@ -310,21 +402,47 @@ namespace Hop::System::Physics size_t size(){return vertices.size();} + /** + * @brief Get a model space primitive. + * + * @param i index of primitive + * @return std::shared_ptr model space primitive. + */ std::shared_ptr getModelVertex(size_t i) { return vertices[i]; } + /** + * @brief Get a world space primitive. + * + * @param i index of primitive. + * @return std::shared_ptr world space primitive. + */ std::shared_ptr getMeshVertex(size_t i) { return worldVertices[i]; } + /** + * @brief Get a world space primitive. + * + * @param i index of primitive. + * @return std::shared_ptr world space primitive. + */ std::shared_ptr operator[](size_t i) { return worldVertices[i]; } + /** + * @brief Update the mesh to a new transform and physics component. + * + * @remark Will integrate mesh points (i.e. handle soft meshes). + * @param transform new transform for the mesh. + * @param physics new physics component for the mesh. + * @param dt timestep. + */ void updateWorldMesh( cTransform & transform, cPhysics & physics, @@ -342,27 +460,62 @@ namespace Hop::System::Physics } } + /** + * @brief Updates the mesh if it is rigid. + * + * @param transform new transform. + * @param dt timestep. + */ void updateWorldMeshRigid( const cTransform & transform, double dt ); + /** + * @brief Update the world mesh if it is soft. + * + * @remark Applies internal soft-body forces. + * @param transform new transform. + * @param physics mesh physics components. + * @param dt timestep. + */ void updateWorldMeshSoft( cTransform & transform, cPhysics & physics, double dt ); + /** + * @brief The optimal angle to represent the mesh in world space. + * + * @param x x coordinate of the mesh. + * @param y y coordinate of the mesh. + * @param scaleX scale of mesh in x. + * @param scaleY scale of mesh in y. + * @return double optimal orientation. + */ double bestAngle(double x, double y, double scaleX, double scaleY); + void centerOfMassWorld(double & cx, double & cy); + + /** + * @brief Rebase coordinates to centre of mess. + * + */ void modelToCenterOfMassFrame(); double momentOfInertia(double x, double y, double mass); + void computeRadius(); + double getRadius(){return radius;} bool getIsRigid(){ return isRigid; } + /** + * @brief Determine if all mesh points are rigid. + * + */ void calculateIsRigid() { for (auto v : worldVertices) @@ -425,6 +578,12 @@ namespace Hop::System::Physics } } + /** + * @brief Get all world space primitives by tag. + * + * @param t tag to match. + * @return std::vector> world primitives matching the tag. + */ std::vector> getByTag(uint64_t t) { std::vector> v; @@ -444,6 +603,12 @@ namespace Hop::System::Physics return v; } + /** + * @brief Get all model space primitives by tag. + * + * @param t tag to select. + * @return std::vector> model primitives matching tag. + */ std::vector> getModelByTag(uint64_t t) { std::vector> v; @@ -463,6 +628,11 @@ namespace Hop::System::Physics return v; } + /** + * @brief Remove all primitives matching tag. + * + * @param t tag to match. + */ void removeByTag(uint64_t t) { std::vector> v; @@ -486,11 +656,22 @@ namespace Hop::System::Physics } } + /** + * @brief Get the world-space bounding box. + * + * @return Hop::Maths::BoundingBox + */ Hop::Maths::BoundingBox getBoundingBox() const { return getBoundingBox(worldVertices); } + /** + * @brief Get the bounding box of a list of primitives. + * + * @param c primitives to bound. + * @return Hop::Maths::BoundingBox + */ Hop::Maths::BoundingBox getBoundingBox ( const std::vector> & c @@ -518,6 +699,12 @@ namespace Hop::System::Physics return Hop::Maths::boundingBox(v, r); } + /** + * @brief Get the bounding box of all primitives with tag. + * + * @param tag tag to match. + * @return Hop::Maths::BoundingBox + */ Hop::Maths::BoundingBox getBoundingBox(uint64_t tag) { std::vector> c = getByTag(tag);