// // Created by Иван Ильин on 05.02.2021. // #ifndef ENGINE_RIGIDBODY_H #define ENGINE_RIGIDBODY_H #include #include #include #include "../Triangle.h" #include "Simplex.h" #include "../Mesh.h" struct CollisionPoint { const Vec3D normal; const double depth; }; struct FaceNormal { const Vec3D normal; const double distance; }; struct NextSimplex { const Simplex newSimplex; const Vec3D newDirection; const bool finishSearching; }; class RigidBody : public Mesh { private: Vec3D _findFurthestPoint(const Vec3D& direction); Vec3D _support(std::shared_ptr obj, const Vec3D& direction); std::function)> _collisionCallBack; static NextSimplex _nextSimplex(const Simplex& points); static NextSimplex _lineCase(const Simplex& points); static NextSimplex _triangleCase(const Simplex& points); static NextSimplex _tetrahedronCase(const Simplex& points); static std::pair>, size_t> _getFaceNormals(const std::vector& polytope, const std::vector& faces); static std::vector> _addIfUniqueEdge(const std::vector>& edges, const std::vector& faces, size_t a, size_t b); static void makeLogObjPolytope(const std::vector& polytope, const std::vector& faces); protected: std::unique_ptr _velocity = std::make_unique(Vec3D{0, 0, 0});; std::unique_ptr _acceleration = std::make_unique(Vec3D{0, 0, 0});; bool _collision = false; bool _isCollider = true; bool _inCollision = false; std::shared_ptr _collisionNormal = std::make_unique(Vec3D{0, 0, 0});; public: RigidBody() = default; explicit RigidBody(const Mesh& mesh); [[nodiscard]] std::pair checkGJKCollision(std::shared_ptr obj); [[nodiscard]] CollisionPoint EPA(const Simplex& simplex, std::shared_ptr obj); void solveCollision(const CollisionPoint& collision); [[nodiscard]] Vec3D collisionNormal() const { return *_collisionNormal; } [[nodiscard]] bool isCollision() const { return _collision; } [[nodiscard]] bool inCollision() const {return _inCollision; } [[nodiscard]] bool isCollider() const {return _isCollider; } void setInCollision(bool c) { _inCollision = c; } void setCollision(bool c) { _collision= c; } void setCollider(bool c) { _isCollider = c; } void updatePhysicsState(); void setVelocity(const Vec3D& velocity); void addVelocity(const Vec3D& velocity); void setAcceleration(const Vec3D& acceleration); [[nodiscard]] Vec3D velocity() const { return *_velocity; } [[nodiscard]] Vec3D acceleration() const { return *_acceleration; } [[nodiscard]] const std::function)>& collisionCallBack() const { return _collisionCallBack; } void setCollisionCallBack(const std::function)>& f) { _collisionCallBack = f; } ~RigidBody() override = default; }; #endif //INC_3DZAVR_RIGIDBODY_H