45                         QT_TR_NOOP("Enable global error calculation"), errorsCalculation, setErrorsCalculation))
 
   47 Item& Item::operator=(const Item& item)
 
   49     Object::operator=(item);
 
   54     if(item._objectErrors) {
 
   55         _objectErrors = 
static_cast<ObjectErrors*
>(
 
   56             item._objectErrors->metaObject()->cloneObject(*item._objectErrors) );
 
   57         _objectErrors->setOwner(
this);
 
   81     ItemList::const_iterator end = _items.end();
 
   82     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
 
   83         (*it)->setWorld(world);
 
   89     ItemList::const_iterator end = _items.end();
 
   90     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
 
   91         (*it)->worldItemRemoved(item);
 
   96     _items.push_back(item);
 
  111     ItemList::iterator i = std::find(_items.begin(), _items.end(), 
item);
 
  118     ItemList::const_iterator end = _items.end();
 
  119     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
 
  120         (*it)->setWorld(NULL);
 
  121         (*it)->setGroup(NULL);
 
  125     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
 
  152     if(
this == &group) 
return *
this;
 
  156     _items.reserve(group._items.size());
 
  158     const ItemList::const_iterator gr_end = group._items.end();
 
  159     for(ItemList::const_iterator it = group._items.begin(); it != gr_end; ++it) {
 
  161         _items.push_back(item);
 
  164     const ItemList::const_iterator end = _items.end();
 
  165     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
 
  166         (*it)->setGroup(
this);
 
  178     ItemList::const_iterator o = std::find(_items.begin(), _items.end(), 
item);
 
  180     return std::distance(_items.begin(), o);
 
  185     ItemList::const_iterator end = _items.end();
 
  186     for(ItemList::const_iterator it = _items.begin(); it != end; ++it)
 
  187         if((*it)->name() == 
name) 
return *it;
 
  193     if(name.
isEmpty()) 
return NULL;
 
  194     ItemList::const_iterator end = _items.end();
 
  195     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
 
  196         if((*it)->name() == 
name) 
return *it;
 
  197         if((*it)->metaObject()->inherits<
ItemGroup>()) {
 
  207     items->reserve(_items.size());
 
  208     ItemList::const_iterator end = _items.end();
 
  209     for(ItemList::const_iterator it = _items.begin(); it != end; ++it) {
 
  210         items->push_back(*it);
 
  211         if((*it)->metaObject()->inherits<
ItemGroup>())
 
  221     int totalConstraintsCount = newConstraintsCount+newContactsCount;
 
  223     jacobian.resize(totalConstraintsCount, newVariablesCount);
 
  226     force.resize(newVariablesCount);
 
  227     value.resize(totalConstraintsCount);
 
  229     if (totalConstraintsCount>0)
 
  234     forceMin.resize(totalConstraintsCount);
 
  235     forceMax.resize(totalConstraintsCount);
 
  260     : _time(0), _timeScale(1), _errorsCalculation(false),
 
  261       _solver(NULL), _collisionSolver(NULL), _constraintSolver(NULL),
 
  270     : 
ItemGroup(), _time(0), _timeScale(1), _errorsCalculation(false),
 
  271       _solver(NULL), _collisionSolver(NULL), _constraintSolver(NULL),
 
  285     if(_collisionSolver) _collisionSolver->
resetCaches();
 
  296     delete _solver; _solver = NULL;
 
  297     delete _collisionSolver; _collisionSolver = NULL;
 
  298     delete _constraintSolver; _constraintSolver = NULL;
 
  301     _variables.resize(0);
 
  302     _variances.resize(0);
 
  303     _tempArray.resize(0);
 
  312     _errorsCalculation = 
false;
 
  314     _stopOnCollision = 
false;
 
  315     _stopOnIntersection = 
false;
 
  316     _evolveAbort = 
false;
 
  318 #ifdef STEPCORE_WITH_QT 
  325     if(
this == &world) 
return *
this;
 
  332                 world._solver->metaObject()->cloneObject(*(world._solver))));
 
  335     if(world._collisionSolver) {
 
  337                world._collisionSolver->metaObject()->cloneObject(*(world._collisionSolver))));
 
  341                world._constraintSolver->metaObject()->cloneObject(*(world._constraintSolver))));
 
  345     _timeScale = world._timeScale;
 
  346     _errorsCalculation = world._errorsCalculation;
 
  348     _stopOnCollision = world._stopOnCollision;
 
  349     _stopOnIntersection = world._stopOnIntersection;
 
  350     _evolveAbort = world._evolveAbort;
 
  354     copyMap.
insert(NULL, NULL);
 
  355     copyMap.
insert(&world, 
this);
 
  356     if(_solver) copyMap.
insert(world._solver, _solver);
 
  357     if(_collisionSolver) copyMap.
insert(world._collisionSolver, _collisionSolver);
 
  358     if(_constraintSolver) copyMap.
insert(world._constraintSolver, _constraintSolver);
 
  359     fillCopyMap(©Map, &world, 
this);
 
  361     applyCopyMap(©Map, 
this);
 
  362     if(_solver) applyCopyMap(©Map, _solver);
 
  363     if(_collisionSolver) applyCopyMap(©Map, _collisionSolver);
 
  364     if(_constraintSolver) applyCopyMap(©Map, _constraintSolver);
 
  366     const ItemList::const_iterator end = 
items().end();
 
  367     for(ItemList::const_iterator it = 
items().begin(); it != end; ++it) {
 
  368         worldItemCopied(©Map, *it);
 
  373     checkVariablesCount();
 
  381     const ItemList::const_iterator end = g1->
items().end();
 
  382     for(ItemList::const_iterator it1 = g1->
items().begin(),
 
  383                                  it2 = g2->
items().begin();
 
  384                                  it1 != end; ++it1, ++it2) {
 
  387             fillCopyMap(map, static_cast<ItemGroup*>(*it1), static_cast<ItemGroup*>(*it2));
 
  396         if(pr->
userTypeId() == qMetaTypeId<Object*>()) {
 
  406     applyCopyMap(map, item);
 
  408     if(item->metaObject()->inherits<Force>())
 
  409         _forces.push_back(dynamic_cast<Force*>(item));
 
  410     if(item->metaObject()->inherits<Joint>())
 
  411         _joints.push_back(dynamic_cast<Joint*>(item));
 
  412     if(item->metaObject()->inherits<Body>())
 
  413         _bodies.push_back(dynamic_cast<Body*>(item));
 
  415     if(item->metaObject()->inherits<
ItemGroup>()) {
 
  417         ItemList::const_iterator end = group->items().end();
 
  418         for(ItemList::const_iterator it = group->items().begin(); it != end; ++it) {
 
  419             worldItemCopied(map, *it);
 
  424 void World::worldItemAdded(Item* item)
 
  426     if(item->metaObject()->inherits<Force>())
 
  427         _forces.push_back(dynamic_cast<Force*>(item));
 
  429     if(item->metaObject()->inherits<Joint>())
 
  430         _joints.push_back(dynamic_cast<Joint*>(item));
 
  432     if(item->metaObject()->inherits<Body>()) {
 
  433         Body* body = 
dynamic_cast<Body*
>(
item);
 
  434         _bodies.push_back(body);
 
  435         if(_collisionSolver) _collisionSolver->
bodyAdded(_bodies, body);
 
  438     if(item->metaObject()->inherits<
ItemGroup>()) {
 
  440         ItemList::const_iterator end = group->items().end();
 
  441         for(ItemList::const_iterator it = group->items().begin(); it != end; ++it) {
 
  446     checkVariablesCount();
 
  449 void World::worldItemRemoved(Item* item)
 
  451     if(item->metaObject()->inherits<
ItemGroup>()) {
 
  453         ItemList::const_iterator end = group->items().end();
 
  454         for(ItemList::const_iterator it = group->items().begin(); it != end; ++it) {
 
  455             worldItemRemoved(*it);
 
  459     const ItemList::const_iterator end = 
items().end();
 
  460     for(ItemList::const_iterator it = 
items().begin(); it != end; ++it) {
 
  461         (*it)->worldItemRemoved(item);
 
  464     if(item->metaObject()->inherits<Body>()) {
 
  465         Body* body = 
dynamic_cast<Body*
>(
item);
 
  466         if(_collisionSolver) _collisionSolver->
bodyRemoved(_bodies, body);
 
  467         BodyList::iterator b = std::find(_bodies.begin(), _bodies.end(), body);
 
  472     if(item->metaObject()->inherits<Joint>()) {
 
  473         JointList::iterator j = std::find(_joints.begin(), _joints.end(),
 
  474                                             dynamic_cast<Joint*
>(
item));
 
  479     if(item->metaObject()->inherits<Force>()) {
 
  480         ForceList::iterator f = std::find(_forces.begin(), _forces.end(),
 
  481                                             dynamic_cast<Force*
>(
item));
 
  487     checkVariablesCount();
 
  551     if(name.
isEmpty()) 
return NULL;
 
  552     if(this->
name() == 
name) 
return this;
 
  553     else if(_solver && _solver->
name() == 
name) 
return _solver;
 
  554     else if(_collisionSolver && _collisionSolver->
name() == 
name) 
return _collisionSolver;
 
  555     else if(_constraintSolver && _constraintSolver->
name() == 
name) 
return _constraintSolver;
 
  556     else return item(name);
 
  579     delete _collisionSolver;
 
  586     _collisionSolver = NULL;
 
  592     delete _constraintSolver;
 
  599     _constraintSolver = NULL;
 
  603 void World::checkVariablesCount()
 
  605     int variablesCount = 0;
 
  606     for(BodyList::iterator b = _bodies.begin(); b != _bodies.end(); ++b) {
 
  607         (*b)->setVariablesOffset(variablesCount);
 
  608         variablesCount += (*b)->variablesCount();
 
  611     int constraintsCount = 0;
 
  612     for(JointList::iterator j = _joints.begin(); j != _joints.end(); ++j) {
 
  613         constraintsCount += (*j)->constraintsCount();
 
  616     _constraintsInfo.
setDimension(variablesCount, constraintsCount, 0);
 
  618     if(variablesCount != _variablesCount) {
 
  619         _variablesCount = variablesCount;
 
  620         _variables.resize(_variablesCount*2);
 
  621         _variances.resize(_variablesCount*2);
 
  622         _tempArray.resize(_variablesCount*2);
 
  627 void World::gatherAccelerations(
double* acceleration, 
double* accelerationVariance)
 
  629     if(accelerationVariance)
 
  630         memset(accelerationVariance, 0, _variablesCount*
sizeof(*accelerationVariance));
 
  633     const BodyList::const_iterator it_end = _bodies.end();
 
  634     for(BodyList::iterator b = _bodies.begin(); b != it_end; ++b) {
 
  635         (*b)->getAccelerations(acceleration + index, accelerationVariance ? accelerationVariance + index : NULL);
 
  636         index += (*b)->variablesCount();
 
  640 void World::gatherVariables(
double* variables, 
double* variances)
 
  642     if(variances) memset(variances, 0, _variablesCount*2*
sizeof(*variances));
 
  645     const BodyList::const_iterator it_end = _bodies.end();
 
  646     for(BodyList::iterator b = _bodies.begin(); b != it_end; ++b) {
 
  647         (*b)->getVariables(variables + index, variables + _variablesCount + index,
 
  648                            variances ? variances + index : NULL,
 
  649                            variances ? variances + _variablesCount + index : NULL);
 
  650         index += (*b)->variablesCount();
 
  654 void World::scatterVariables(
const double* variables, 
const double* variances)
 
  657     const BodyList::const_iterator it_end = _bodies.end();
 
  658     for(BodyList::iterator b = _bodies.begin(); b != it_end; ++b) {
 
  659         (*b)->setVariables(variables + index,  variables + _variablesCount + index,
 
  660                            variances ? variances + index : NULL,
 
  661                            variances ? variances + _variablesCount + index : NULL);
 
  662         index += (*b)->variablesCount();
 
  666 void World::gatherJointsInfo(ConstraintsInfo* info)
 
  671     const BodyList::const_iterator b_end = _bodies.end();
 
  672     for(BodyList::iterator body = _bodies.begin(); body != b_end; ++body) {
 
  673         (*body)->getInverseMass(&(info->inverseMass), NULL, offset);
 
  674         offset += (*body)->variablesCount();
 
  678     const JointList::const_iterator j_end = _joints.end();
 
  679     for(JointList::iterator joint = _joints.begin(); joint != j_end; ++joint) {
 
  680         (*joint)->getConstraintsInfo(info, offset);
 
  681         offset += (*joint)->constraintsCount();
 
  691     _stopOnCollision = 
false;
 
  692     _stopOnIntersection = 
false;
 
  693     checkVariablesCount();
 
  694     gatherVariables(_variables.data(), _errorsCalculation ? _variances.data() : NULL);
 
  695     return _solver->
doCalcFn(&_time, &_variables, _errorsCalculation ? &_variances : NULL,
 
  696                              NULL, _errorsCalculation ? &_variances : NULL);
 
  703     checkVariablesCount();
 
  704     gatherVariables(_variables.data(), _errorsCalculation ? _variances.data() : NULL);
 
  707     double targetTime = _time + delta*_timeScale;
 
  709     if(_collisionSolver) {
 
  715     while(_time < targetTime) {
 
  717         if( !(   targetTime - _time > _solver->
stepSize() / 1000 ) ) {
 
  718                     qDebug(
"* %e %e %e", targetTime, _time, _solver->
stepSize());
 
  722         _stopOnCollision = 
true;
 
  723         _stopOnIntersection = 
true;
 
  725         ret = _solver->
doEvolve(&time, targetTime, &_variables,
 
  726                             _errorsCalculation ? &_variances : NULL);
 
  742             double stepSize = fmin(_solver->
stepSize() / 2, targetTime - _time);
 
  743             double collisionEndTime = targetTime - _time > stepSize*3.01 ? _time + stepSize*3 : targetTime;
 
  745             _stopOnCollision = 
false;
 
  748                 double endTime = collisionEndTime - time > stepSize*1.01 ? time+stepSize : collisionEndTime;
 
  750                 ret = _solver->
doEvolve(&time, endTime, &_variables,
 
  751                             _errorsCalculation ? &_variances : NULL);
 
  758                     stepSize = fmin(stepSize/2, targetTime - _time);
 
  759                     collisionEndTime = targetTime - _time > stepSize*3.01 ? _time + stepSize*3 : targetTime;
 
  771                     scatterVariables(_variables.data(), _errorsCalculation ? _variances.data() : NULL);
 
  774                     int contactsCount = 0;
 
  775                     int status = _collisionSolver->
checkContacts(_bodies, 
true, &contactsCount);
 
  783                     _tempArray.setZero();
 
  785                     ::new (&_constraintsInfo.
velocity) 
MappedVector(_variables.data()+_variablesCount, _variablesCount);
 
  789                     gatherJointsInfo(&_constraintsInfo);
 
  798                         ret = _constraintSolver->
solve(&_constraintsInfo);
 
  806             } 
while(_time + stepSize/100 <= collisionEndTime); 
 
  811     scatterVariables(_variables.data(), _errorsCalculation ? _variances.data() : NULL);
 
  815 inline int World::solverFunction(
double t, 
const double* y,
 
  816                     const double* yvar, 
double* f, 
double* fvar)
 
  821     scatterVariables(y, yvar); 
 
  824     bool calcVariances = (fvar != NULL);
 
  825     const ForceList::const_iterator f_end = _forces.end();
 
  826     for(ForceList::iterator force = _forces.begin(); force != f_end; ++force) {
 
  827         (*force)->calcForce(calcVariances);
 
  830     std::memcpy(f, y+_variablesCount, _variablesCount*
sizeof(*f));
 
  831     if(fvar) std::memcpy(fvar, y+_variablesCount, _variablesCount*
sizeof(*fvar));
 
  832     gatherAccelerations(f+_variablesCount, fvar ? fvar+_variablesCount : NULL);
 
  834     if (_constraintSolver)
 
  840       if(_collisionSolver) {
 
  841           int contactsCount = 0;
 
  842           state = _collisionSolver->
checkContacts(_bodies, 
false, &contactsCount);
 
  852       if(_variablesCount>0)
 
  855         ::new (&_constraintsInfo.velocity) 
MappedVector(y+_variablesCount, _variablesCount);
 
  856         ::new (&_constraintsInfo.acceleration) 
MappedVector(f+_variablesCount, _variablesCount);
 
  862       gatherJointsInfo(&_constraintsInfo);
 
  865       if(_collisionSolver) {
 
  866           _collisionSolver->getContactsInfo(_constraintsInfo, 
false);
 
  888       if(_constraintsInfo.constraintsCount + _constraintsInfo.contactsCount > 0) {
 
  890           int state = _constraintSolver->
solve(&_constraintsInfo);
 
  894           const BodyList::const_iterator b_end = _bodies.end();
 
  895           for(BodyList::iterator body = _bodies.begin(); body != b_end; ++body) {
 
  896               (*body)->addForce(&_constraintsInfo.force[offset], NULL);
 
  897               (*body)->getAccelerations(f+_variablesCount+offset, NULL);
 
  898               offset += (*body)->variablesCount();
 
  906 int World::solverFunction(
double t, 
const double* y,
 
  907                 const double* yvar, 
double* f, 
double* fvar, 
void* params)
 
  909     return static_cast<World*
>(params)->solverFunction(t, y, yvar, f, fvar);
 
DynSparseRowMatrix jacobianDerivative
Time-derivative of constraintsJacobian. 
CollisionSolver * removeCollisionSolver()
Get current CollisionSolver and remove it from world. 
ConstraintSolver * constraintSolver() const 
Get current ConstraintSolver. 
void deleteObjectErrors()
Delete objectErrors. 
Item * item(const QString &name) const 
Get any descendant item by its name. 
iterator insert(const Key &key, const T &value)
Object * object(const QString &name)
Add new item to the world. 
VectorXd value
Current constarints values (amount of brokenness) 
MappedVector acceleration
Accelerations of the bodies before applying constraints. 
virtual int doEvolve(double *t, double t1, VectorXd *y, VectorXd *yvar)=0
Integrate. 
#define STEPCORE_ASSERT_NOABORT(expr)
virtual int solve(ConstraintsInfo *info)=0
ConstraintSolver * removeConstraintSolver()
Get current ConstraintSolver and remove it from world. 
void worldItemRemoved(Item *item)
Recursively call worldItemRemoved for all children objects. 
int contactsCount
Number of additional constrains equations due to contacts. 
Item & operator=(const Item &item)
Assignment operator (copies objectErrors if necessary) 
Root of the StepCore classes hierarchy. 
int variablesCount
Number of dynamic variables. 
~ItemGroup()
Destroys the group and all its subitems. 
virtual void setGroup(ItemGroup *group)
Set/change pointer to ItemGroup in which this object lives. 
MappedVector velocity
Velocities of the bodies. 
Generic Solver interface. 
void clear()
Deletes all items. 
Item * childItem(int index) const 
Get direct child item by its index. 
STEPCORE_SUPER_CLASS(CollisionSolver)
World()
Constructs empty World. 
VectorXd forceMin
Constraints force lower limit. 
void setDimension(int newVariablesCount, int newConstraintsCount, int newContactsCount=0)
Set variablesCount, constraintsCount and reset contactsCount, resize all arrays appropriately. 
CollisionSolver interface. 
virtual void removeItem(Item *item)
Remove item from the group (you should delete item youself) 
int constraintsCount
Number of constraints equations. 
virtual void getContactsInfo(ConstraintsInfo &info, bool collisions=false)=0
Fill the constraint info structure with the contacts computed by checkContacts() 
int doEvolve(double delta)
Integrate. 
World * world() const 
Get pointer to World in which this object lives. 
Item, Body, Force and Tool interfaces, World class. 
virtual void addItem(Item *item)
Add new item to the group. 
DynSparseRowMatrix jacobian
Position-derivative of constraints values. 
QT_TRANSLATE_NOOP("ObjectClass","GJKCollisionSolver")
ItemGroup * group() const 
Get pointer to ItemGroup in which this object lives. 
Eigen::Map< Eigen::VectorXd > MappedVector
void setColor(Color color)
Set item color (for use in GUI) 
VectorXd forceMax
Constraints force upper limit. 
~World()
Destroys World and all objects which belongs to it. 
virtual void bodyRemoved(BodyList &, Body *)
Solver * solver() const 
Get current Solver. 
ConstraintSolver interface. 
void setSolver(Solver *solver)
Set new Solver (and delete the old one) 
virtual void setParams(void *params)
Set callback function params. 
The root class for any world items (bodies and forces) 
int childItemIndex(const Item *item) const 
Finds direct child item in items() 
VectorXd derivative
Time-derivative of constraints values. 
virtual ObjectErrors * createObjectErrors()
Base class for all errors objects. 
const QString & name() const 
Returns name of the object. 
Object(const QString &name=QString())
QT_TR_NOOP("Errors class for CoulombForce")
STEPCORE_PROPERTY_RW(double, depth, QT_TRANSLATE_NOOP("PropertyName","depth"), QT_TRANSLATE_NOOP("Units","J"), QT_TR_NOOP("Potential depth"), depth, setDepth) STEPCORE_PROPERTY_RW(double
const T value(const Key &key) const
Groups several items together. 
Collision solver interface. 
QVariant fromValue(const T &value)
virtual void setFunction(Function function)
Set callback function. 
std::vector< Item * > ItemList
List of pointers to Item. 
#define STEPCORE_UNITS_NULL
virtual void bodyAdded(BodyList &, Body *)
CollisionSolver * collisionSolver() const 
Get current CollisionSolver. 
void setWorld(World *world)
Recursively call setWorld for all children objects. 
STEPCORE_PROPERTY_RW_D(StepCore::Vector2d, positionVariance, QT_TRANSLATE_NOOP("PropertyName","positionVariance"), QT_TRANSLATE_NOOP("Units","m"), QT_TR_NOOP("position variance"), positionVariance, setPositionVariance) STEPCORE_PROPERTY_RW_D(double
void setCollisionSolver(CollisionSolver *collisionSolver)
Set new CollisionSolver (and delete the old one) 
World & operator=(const World &world)
Assignment operator (deep copy) 
void clear()
Clear world (removes all items, solver and resets time) 
ObjectErrors * objectErrors()
Get existing ObjectErrors or try to create it. 
virtual int checkContacts(BodyList &bodies, bool collisions=false, int *count=NULL)=0
Check (and update) state of the contact. 
void setName(const QString &name)
Set name of the object. 
double stepSize() const 
Get step size. 
virtual int doCalcFn(double *t, const VectorXd *y, const VectorXd *yvar=0, VectorXd *f=0, VectorXd *fvar=0)=0
Calculate function value. 
VectorXd inverseMass
Diagonal coefficients of the inverse mass matrix of the system. 
const ItemList & items() const 
Get list of all direct child items in the ItemGroup. 
virtual void setWorld(World *world)
Set/change pointer to World in which this object lives. 
STEPCORE_META_OBJECT(CollisionSolver, QT_TRANSLATE_NOOP("ObjectClass","CollisionSolver"),"CollisionSolver", MetaObject::ABSTRACT, STEPCORE_SUPER_CLASS(Object), STEPCORE_PROPERTY_RW(double, toleranceAbs, QT_TRANSLATE_NOOP("PropertyName","toleranceAbs"), STEPCORE_UNITS_1, QT_TR_NOOP("Allowed absolute tolerance"), toleranceAbs, setToleranceAbs) STEPCORE_PROPERTY_R_D(double, localError, QT_TRANSLATE_NOOP("PropertyName","localError"), STEPCORE_UNITS_1, QT_TR_NOOP("Maximal local error during last step"), localError)) STEPCORE_META_OBJECT(GJKCollisionSolver
virtual void setDimension(int dimension)
Set ODE dimension. 
MappedVector position
Positions of the bodies. 
Solver * removeSolver()
Get current Solver and remove it from world. 
VectorXd force
Resulting constraints force. 
Constraint solver interface. 
ItemGroup & operator=(const ItemGroup &group)
Assignment operator (deep copy) 
void clear()
Clear the structure. 
Contains multiple Item, Solver and general properties such as time. 
void setConstraintSolver(ConstraintSolver *constraintSolver)
Set new ConstraintSolver (and delete the old one) 
bool collisionFlag
True if there is a collision to be resolved. 
ItemGroup(const QString &name=QString())
Constructs empty group. 
virtual void resetCaches()
Reset internal caches of collision information. 
double time() const 
Get current time. 
int doCalcFn()
Calculate all forces. 
ItemList allItems() const 
Get list of all items in the ItemGroup.