File indexing completed on 2024-09-08 06:38:02
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 world.h 0008 * \brief Item, Body, Force and Tool interfaces, World class 0009 */ 0010 0011 #ifndef STEPCORE_WORLD_H 0012 #define STEPCORE_WORLD_H 0013 0014 0015 // stdc++ 0016 #include <vector> // XXX: replace if QT is enabled 0017 0018 // Qt 0019 #include <QHash> 0020 0021 // Stepcore 0022 #include "types.h" 0023 #include "util.h" 0024 #include "vector.h" 0025 #include "object.h" 0026 #include "item.h" 0027 #include "body.h" 0028 #include "force.h" 0029 #include "joint.h" 0030 #include "itemgroup.h" 0031 0032 0033 // TODO: split this file 0034 0035 namespace StepCore 0036 { 0037 0038 class World; 0039 class Solver; 0040 class Item; 0041 class CollisionSolver; 0042 class ConstraintSolver; 0043 0044 0045 /** \ingroup tools 0046 * \brief Interface for tools 0047 * 0048 * Tools are not physical objects in simulation but utilities to control 0049 * simulation or obtain some information 0050 */ 0051 class Tool 0052 { 0053 STEPCORE_OBJECT(Tool) 0054 public: 0055 virtual ~Tool() {} 0056 }; 0057 0058 /** \ingroup world 0059 * \brief Contains multiple Item, Solver and general properties such as time 0060 * \todo Redesign to avoid variable copying (scatter/gatherVariables) 0061 */ 0062 class World : public ItemGroup 0063 { 0064 /*Q_OBJECT*/ 0065 STEPCORE_OBJECT(World) 0066 0067 public: 0068 /** Constructs empty World */ 0069 World(); 0070 /** Constructs a copy of world (deep copy) */ 0071 World(const World& world); 0072 /** Destroys World and all objects which belongs to it */ 0073 ~World(); 0074 0075 /** Assignment operator (deep copy) */ 0076 World& operator=(const World& world); 0077 0078 0079 /** Clear world (removes all items, solver and resets time) */ 0080 void clear(); 0081 0082 /** Get current time */ 0083 double time() const { return _time; } 0084 /** Set current time */ 0085 void setTime(double t) { _time = t; } 0086 0087 /** Get simulation speed scale */ 0088 double timeScale() const { return _timeScale; } 0089 /** Set simulation speed scale */ 0090 void setTimeScale(double timeScale) { _timeScale = timeScale; } 0091 0092 /** Is errors calculation enabled */ 0093 bool errorsCalculation() const { return _errorsCalculation; } 0094 /** Enable or disable errors calculation */ 0095 void setErrorsCalculation(bool errorsCalculation) { 0096 _errorsCalculation = errorsCalculation; } 0097 0098 /** Add new item to the world */ 0099 //void addItem(Item* item); 0100 /** Remove item from the world (you should delete item yourself) */ 0101 //void removeItem(Item* item); 0102 /** Delete item from the world (it actually deletes item) */ 0103 //void deleteItem(Item* item) { removeItem(item); delete item; } 0104 /** Finds item in items() */ 0105 //int itemIndex(const Item* item) const; 0106 0107 /** Get item by its index */ 0108 //Item* item(int index) const { return _items[index]; } 0109 /** Get item by its name */ 0110 //Item* item(const QString& name) const; 0111 /** Get object (item, solver, *Solver or world itself) by its name */ 0112 Object* object(const QString& name); 0113 0114 /** Get list of all items (not including sub-items) in the World */ 0115 //const ItemList& items() const { return _items; } 0116 /** Get list of all bodies (including sub-items) in the World */ 0117 const BodyList& bodies() const { return _bodies; } 0118 /** Get list of all forces (including sub-items) in the World */ 0119 const ForceList& forces() const { return _forces; } 0120 /** Get list of all joints (including sub-items) in the World */ 0121 const JointList& joints() const { return _joints; } 0122 0123 /** Get current Solver */ 0124 Solver* solver() const { return _solver; } 0125 /** Set new Solver (and delete the old one) */ 0126 void setSolver(Solver* solver); 0127 /** Get current Solver and remove it from world */ 0128 Solver* removeSolver(); 0129 0130 /** Get current CollisionSolver */ 0131 CollisionSolver* collisionSolver() const { return _collisionSolver; } 0132 /** Set new CollisionSolver (and delete the old one) */ 0133 void setCollisionSolver(CollisionSolver* collisionSolver); 0134 /** Get current CollisionSolver and remove it from world */ 0135 CollisionSolver* removeCollisionSolver(); 0136 0137 /** Get current ConstraintSolver */ 0138 ConstraintSolver* constraintSolver() const { return _constraintSolver; } 0139 /** Set new ConstraintSolver (and delete the old one) */ 0140 void setConstraintSolver(ConstraintSolver* constraintSolver); 0141 /** Get current ConstraintSolver and remove it from world */ 0142 ConstraintSolver* removeConstraintSolver(); 0143 0144 /** Calculate all forces */ 0145 int doCalcFn(); 0146 /** Integrate. 0147 * \param delta Integration interval 0148 * \return the same as Solver::doEvolve 0149 * \todo Provide error message 0150 */ 0151 int doEvolve(double delta); 0152 0153 /** Get evolveAbort flag (can be called from separate thread) */ 0154 bool evolveAbort() { return _evolveAbort; } 0155 /** Set evolveAbort flag (can be called from separate thread). When the flag is set 0156 * current (or any subsequent) doEvolve operation will be aborted as soon as possible. */ 0157 void setEvolveAbort(bool evolveAbort = true) { _evolveAbort = evolveAbort; } 0158 0159 private: 0160 friend class ItemGroup; 0161 0162 /** \internal Creates a map between pointers to items in two groups 0163 * (groups should contain identical items). */ 0164 void fillCopyMap(QHash<const Object*, Object*>* map, 0165 const ItemGroup* g1, ItemGroup* g2); 0166 /** \internal Maps all links to other objects in obj using the map */ 0167 void applyCopyMap(QHash<const Object*, Object*>* map, Object* obj); 0168 /** \internal Recursively add item and all its children into 0169 * bodies, forces and joints arrays. Calls applyCopyMap for them. 0170 * Called by World::operator=() */ 0171 void worldItemCopied(QHash<const Object*, Object*>* map, Item* item); 0172 /** \internal Recursively add item and all its children into 0173 * bodies, forces and joints arrays. Called by ItemGroup::addItem() */ 0174 void worldItemAdded(Item* item); 0175 /** \internal Recursively remove item and all its children from 0176 * bodies, forces and joints arrays. Called by ItemGroup::removeItem() 0177 * and ItemGroup::clear() */ 0178 void worldItemRemoved(Item* item) override; 0179 0180 /** \internal This function iterates over all bodies, assigns indexes 0181 * for them in the global array (_variables), calculates total 0182 * variables count and reallocates (if necessary) _variables and 0183 * _variances arrays. It does the same for joints. */ 0184 void checkVariablesCount(); 0185 0186 /** \internal Gathers acceleration (and possibly their variances) 0187 * from all bodies into one array */ 0188 void gatherAccelerations(double* acceleration, double* variance); 0189 0190 /** \internal Gathers variables (and possibly their variances) 0191 * from all bodies into one array */ 0192 void gatherVariables(double* variables, double* variances); 0193 0194 /** \internal Scatters variable (and possibly their variances) 0195 * from one array to all bodies */ 0196 void scatterVariables(const double* variables, const double* variances); 0197 0198 /** \internal Gather information from all joints */ 0199 void gatherJointsInfo(ConstraintsInfo* info); 0200 0201 /** \internal Static wrapper for World::solverFunction */ 0202 static int solverFunction(double t, const double* y, const double* yvar, 0203 double* f, double* fvar, void* params); 0204 /** \internal Called by solver to calculate variable derivatives. 0205 * This function: 0206 * 1. Checks collisions between bodies and resolves them if it is possible 0207 * 2. Iterates over all forces to calculate total force for each body 0208 * 3. Iterates over all joints and calls constraintSolver to solve them 0209 */ 0210 int solverFunction(double t, const double* y, const double* yvar, 0211 double* f, double* fvar); 0212 0213 private: 0214 double _time; 0215 double _timeScale; 0216 bool _errorsCalculation; 0217 0218 //ItemList _items; 0219 BodyList _bodies; 0220 ForceList _forces; 0221 JointList _joints; 0222 0223 Solver* _solver; 0224 CollisionSolver* _collisionSolver; 0225 ConstraintSolver* _constraintSolver; 0226 0227 int _variablesCount; ///< \internal Count of positions (not including velocities) 0228 VectorXd _variables; ///< \internal Positions and velocities (size == _variablesCount*2) 0229 VectorXd _variances; ///< \internal Variances of positions and velocities 0230 VectorXd _tempArray; ///< \internal Temporary array used in various places 0231 ConstraintsInfo _constraintsInfo; ///< \internal Constraints information 0232 0233 bool _stopOnCollision; 0234 bool _stopOnIntersection; 0235 bool _evolveAbort; 0236 }; 0237 0238 } // namespace StepCore 0239 0240 /** \defgroup world World */ 0241 /** \defgroup vector Fixed-size vector */ 0242 /** \defgroup constants Physical constants */ 0243 /** \defgroup bodies Physical bodies */ 0244 /** \defgroup forces Physical forces */ 0245 /** \defgroup joints Rigid joints */ 0246 /** \defgroup tools Various tools */ 0247 /** \defgroup solvers ODE Solvers */ 0248 /** \defgroup contacts Collision and constraint solvers */ 0249 /** \defgroup reflections Reflections */ 0250 /** \defgroup xmlfile XML file IO */ 0251 /** \defgroup errors ObjectErrors classes */ 0252 0253 #endif 0254