1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
|
/* This file is part of StepCore library.
Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
StepCore library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
StepCore library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with StepCore; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/** \file world.h
* \brief Item, Body, Force and Tool interfaces, World class
*/
#ifndef STEPCORE_WORLD_H
#define STEPCORE_WORLD_H
// stdc++
#include <vector> // XXX: replace if QT is enabled
// Qt
#include <QHash>
// Stepcore
#include "types.h"
#include "util.h"
#include "vector.h"
#include "object.h"
#include "item.h"
#include "body.h"
#include "force.h"
#include "joint.h"
#include "itemgroup.h"
// TODO: split this file
namespace StepCore
{
class World;
class Solver;
class Item;
class CollisionSolver;
class ConstraintSolver;
/** \ingroup tools
* \brief Interface for tools
*
* Tools are not physical objects in simulation but utilities to control
* simulation or obtain some information
*/
class Tool
{
STEPCORE_OBJECT(Tool)
public:
virtual ~Tool() {}
};
/** \ingroup world
* \brief Contains multiple Item, Solver and general properties such as time
* \todo Redesign to avoid variable copying (scatter/gatherVariables)
*/
class World : public ItemGroup
{
/*Q_OBJECT*/
STEPCORE_OBJECT(World)
public:
/** Constructs empty World */
World();
/** Constructs a copy of world (deep copy) */
World(const World& world);
/** Destroys World and all objects which belongs to it */
~World();
/** Assignment operator (deep copy) */
World& operator=(const World& world);
/** Clear world (removes all items, solver and resets time) */
void clear();
/** Get current time */
double time() const { return _time; }
/** Set current time */
void setTime(double t) { _time = t; }
/** Get simulation speed scale */
double timeScale() const { return _timeScale; }
/** Set simulation speed scale */
void setTimeScale(double timeScale) { _timeScale = timeScale; }
/** Is errors calculation enabled */
bool errorsCalculation() const { return _errorsCalculation; }
/** Enable or disable errors calculation */
void setErrorsCalculation(bool errorsCalculation) {
_errorsCalculation = errorsCalculation; }
/** Add new item to the world */
//void addItem(Item* item);
/** Remove item from the world (you should delete item youself) */
//void removeItem(Item* item);
/** Delete item from the world (it actually deletes item) */
//void deleteItem(Item* item) { removeItem(item); delete item; }
/** Finds item in items() */
//int itemIndex(const Item* item) const;
/** Get item by its index */
//Item* item(int index) const { return _items[index]; }
/** Get item by its name */
//Item* item(const QString& name) const;
/** Get object (item, solver, *Solver or worls itself) by its name */
Object* object(const QString& name);
/** Get list of all items (not including sub-items) in the World */
//const ItemList& items() const { return _items; }
/** Get list of all bodies (including sub-items) in the World */
const BodyList& bodies() const { return _bodies; }
/** Get list of all forces (including sub-items) in the World */
const ForceList& forces() const { return _forces; }
/** Get list of all joints (including sub-items) in the World */
const JointList& joints() const { return _joints; }
/** Get current Solver */
Solver* solver() const { return _solver; }
/** Set new Solver (and delete the old one) */
void setSolver(Solver* solver);
/** Get current Solver and remove it from world */
Solver* removeSolver();
/** Get current CollisionSolver */
CollisionSolver* collisionSolver() const { return _collisionSolver; }
/** Set new CollisionSolver (and delete the old one) */
void setCollisionSolver(CollisionSolver* collisionSolver);
/** Get current CollisionSolver and remove it from world */
CollisionSolver* removeCollisionSolver();
/** Get current ConstraintSolver */
ConstraintSolver* constraintSolver() const { return _constraintSolver; }
/** Set new ConstraintSolver (and delete the old one) */
void setConstraintSolver(ConstraintSolver* constraintSolver);
/** Get current ConstraintSolver and remove it from world */
ConstraintSolver* removeConstraintSolver();
/** Calculate all forces */
int doCalcFn();
/** Integrate.
* \param delta Integration interval
* \return the same as Solver::doEvolve
* \todo Provide error message
*/
int doEvolve(double delta);
/** Get evolveAbort flag (can be called from separate thread) */
bool evolveAbort() { return _evolveAbort; }
/** Set evolveAbort flag (can be called from separate thread). When the flag is set
* current (or any subsequent) doEvolve operation will be aborted as soon as possible. */
void setEvolveAbort(bool evolveAbort = true) { _evolveAbort = evolveAbort; }
private:
friend class ItemGroup;
/** \internal Creates a map between pointers to items in two groups
* (groups should contain identical items). */
void fillCopyMap(QHash<const Object*, Object*>* map,
const ItemGroup* g1, ItemGroup* g2);
/** \internal Maps all links to other objects in obj using the map */
void applyCopyMap(QHash<const Object*, Object*>* map, Object* obj);
/** \internal Recursively add item and all its children into
* bodies, forces and joints arrays. Calls applyCopyMap for them.
* Called by World::operator=() */
void worldItemCopied(QHash<const Object*, Object*>* map, Item* item);
/** \internal Recursively add item and all its children into
* bodies, forces and joints arrays. Called by ItemGroup::addItem() */
void worldItemAdded(Item* item);
/** \internal Recursively remove item and all its children from
* bodies, forces and joints arrays. Called by ItemGroup::removeItem()
* and ItemGroup::clear() */
void worldItemRemoved(Item* item);
/** \internal This function iterates over all bodies, assigns indexes
* for them in the global array (_variables), calculates total
* variables count and reallocates (if necessary) _variables and
* _variances arrays. It does the same for joints. */
void checkVariablesCount();
/** \internal Gathers acceleration (and possibly their variances)
* from all bodies into one array */
void gatherAccelerations(double* acceleration, double* variance);
/** \internal Gathers variables (and possibly their variances)
* from all bodies into one array */
void gatherVariables(double* variables, double* variances);
/** \internal Scatters variable (and possibly their variances)
* from one array to all bodies */
void scatterVariables(const double* variables, const double* variances);
/** \internal Gather information from all joints */
void gatherJointsInfo(ConstraintsInfo* info);
/** \internal Static wrapper for World::solverFunction */
static int solverFunction(double t, const double* y, const double* yvar,
double* f, double* fvar, void* params);
/** \internal Called by solver to calculate variable derivatives.
* This function:
* 1. Checks collisions between bodies and resolves them if it is possible
* 2. Iterates over all forces to calculate total force for each body
* 3. Iterates over all joints and calls constraintSolver to solve them
*/
int solverFunction(double t, const double* y, const double* yvar,
double* f, double* fvar);
private:
double _time;
double _timeScale;
bool _errorsCalculation;
//ItemList _items;
BodyList _bodies;
ForceList _forces;
JointList _joints;
Solver* _solver;
CollisionSolver* _collisionSolver;
ConstraintSolver* _constraintSolver;
int _variablesCount; ///< \internal Count of positions (not including velocities)
VectorXd _variables; ///< \internal Positions and velocities (size == _variablesCount*2)
VectorXd _variances; ///< \internal Variances of positions and velocities
VectorXd _tempArray; ///< \internal Temporary array used in various places
ConstraintsInfo _constraintsInfo; ///< \internal Constraints information
bool _stopOnCollision;
bool _stopOnIntersection;
bool _evolveAbort;
};
} // namespace StepCore
/** \defgroup world World */
/** \defgroup vector Fixed-size vector */
/** \defgroup constants Physical constants */
/** \defgroup bodies Physical bodies */
/** \defgroup forces Physical forces */
/** \defgroup joints Rigid joints */
/** \defgroup tools Various tools */
/** \defgroup solvers ODE Solvers */
/** \defgroup contacts Collision and constraint solvers */
/** \defgroup reflections Reflections */
/** \defgroup xmlfile XML file IO */
/** \defgroup errors ObjectErrors classes */
#endif
|