File indexing completed on 2024-04-21 03:51:24

0001 /*
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /** \file softbody.h
0008  *  \brief SoftBody-related classes
0009  */
0010 
0011 #ifndef STEPCORE_SOFTBODY_H
0012 #define STEPCORE_SOFTBODY_H
0013 
0014 #include "particle.h"
0015 #include "spring.h"
0016 #include "world.h"
0017 #include <cmath>
0018 
0019 namespace StepCore {
0020 
0021 /** \ingroup bodies
0022  *  \brief Soft body particle
0023  */
0024 class SoftBodyParticle: public Particle
0025 {
0026     STEPCORE_OBJECT(SoftBodyParticle)
0027 
0028 public:
0029     /** Constructs a SoftBadyParticle */
0030     explicit SoftBodyParticle(const Vector2d &position = Vector2d::Zero(), const Vector2d &velocity = Vector2d::Zero(), double mass = 1)
0031         : Particle(position, velocity, mass) {}
0032 };
0033 
0034 /** \ingroup forces
0035  *  \brief Soft body spring
0036  */
0037 class SoftBodySpring: public Spring
0038 {
0039     STEPCORE_OBJECT(SoftBodySpring)
0040 
0041 public:
0042     /** Constructs a SoftBodySpring */
0043     explicit SoftBodySpring(double restLength = 0, double stiffness = 1, double damping = 0,
0044                                                      Item* bodyPtr1 = nullptr, Item* bodyPtr2 = nullptr)
0045         : Spring(restLength, stiffness, damping, bodyPtr1, bodyPtr2) {}
0046 };
0047 
0048 typedef std::vector<SoftBodyParticle*> SoftBodyParticleList;
0049 
0050 /** \ingroup bodies
0051  *  \brief SoftBody - a group of several SoftBodyParticle and SoftBodySprings
0052  */
0053 class SoftBody: public ItemGroup
0054 {
0055     STEPCORE_OBJECT(SoftBody)
0056 
0057 public:
0058     /** Constructs a SoftBody */
0059     SoftBody(): _showInternalItems(true) { setColor(0xffa9a9a9); }
0060 
0061     /** Creates particles and springs inside soft body
0062      *  \param position Position of the center of the body
0063      *  \param size Size of the edge of the body
0064      *  \param split Split count of the edge of the body
0065      *  \param bodyMass Total mass of the body
0066      *  \param youngModulus Young's modulus of the body
0067      *  \param bodyDamping Damping of the body
0068      *  \return List of particles and springs
0069      */
0070     ItemList createSoftBodyItems(const Vector2d& position, const Vector2d& size, const Vector2i& split,
0071                     double bodyMass, double youngModulus, double bodyDamping);
0072 
0073     /** Adds all items to ItemGroup */
0074     void addItems(const ItemList& items);
0075 
0076     /** Get the position of the center of mass */
0077     Vector2d position() const;
0078     /** Set the position of the center of mass */
0079     void setPosition(const Vector2d &position); 
0080 
0081     /** Get the velocity of the center of mass */
0082     Vector2d velocity() const;
0083     /** Set the velocity of the center of mass */
0084     void setVelocity(const Vector2d &velocity);
0085 
0086     /** Get the angular velocity of the body */
0087     double angularVelocity() const;
0088     /** Set the angular velocity of the body */
0089     void setAngularVelocity(double angularVelocity);
0090 
0091     /** Get the angular momentum of the body */
0092     double angularMomentum() const;
0093 
0094     /** Set the angular momentum of the body */
0095     void setAngularMomentum(double angularMomentum);
0096 
0097     /** Get acceleration of the center of mass */
0098     Vector2d acceleration() const { return force()/mass(); }
0099 
0100     /** Get angular acceleration of the body */
0101     double angularAcceleration() const { return torque()/inertia(); }
0102 
0103     /** Get the force acting on the body */
0104     Vector2d force() const; 
0105     /** Get the torque acting on the body */
0106     double torque() const;
0107 
0108     /** Get total body mass */
0109     double mass() const;
0110 
0111     /** Get the inertia of the body */
0112     double inertia() const;
0113 
0114     /** Get status of drawing of internal items */
0115     bool showInternalItems() const { return _showInternalItems; }
0116     /** Set status of drawing of internal items */
0117     void setShowInternalItems(bool showInternalItems) {
0118         _showInternalItems = showInternalItems; }
0119 
0120     /** Get ordered list of particles on the border of the body */
0121     const SoftBodyParticleList& borderParticles();
0122 
0123     QString borderParticleNames() const;
0124     void setBorderParticleNames(const QString& borderParticleNames);
0125 
0126     void worldItemRemoved(Item* item) override;
0127     void setWorld(World* world) override;
0128 
0129 protected:
0130     SoftBodyParticleList _borderParticles;
0131     QString _borderParticleNames;
0132     bool _showInternalItems;
0133 };
0134 
0135 } // namespace StepCore
0136 
0137 #endif
0138