Commit e90f5725 authored by Inge Wallin's avatar Inge Wallin

Refactor: Separate class Joint from world.h

parent ec8c5cb6
......@@ -21,7 +21,7 @@
#include "worldgraphics.h"
#include "stepgraphicsitem.h"
#include <stepcore/joint.h>
#include <stepcore/joints.h>
class AnchorCreator: public AttachableItemCreator
{
......
......@@ -33,7 +33,7 @@
#include <stepcore/eulersolver.h>
#include <stepcore/collisionsolver.h>
#include <stepcore/constraintsolver.h>
#include <stepcore/joint.h>
#include <stepcore/joints.h>
#include <stepcore/tool.h>
#include <stepcore/types.h>
......
......@@ -44,18 +44,18 @@ Legend
* Body{body.h} Anything that has dynamic variables that
require ODE integration
* Particle(Item, Body)
* Particle
* ChargedParticle
* GasParticle
* RigidBody(Item, Body)
* RigidBody
* Disk
* BasePolygon
* Box
* Polygon
* Plane(Item, Body) Unmovable rigid plane
* Plane Unmovable rigid plane
* Force{world.h} Anything that acts upon bodies changing
* Force Anything that acts upon bodies changing
derivatives of dynamic variables
* CoulombForce Force for charged particles.
* GasLJForce Force within gasses
......
set(stepcore_SRCS
object.cc
constants.cc
# Base objects
object.cc
item.cc
body.cc
objecterrors.cc
force.cc
joint.cc
# Storage objects
world.cc
solver.cc
collisionsolver.cc
constraintsolver.cc
factory.cc
particle.cc
rigidbody.cc
......@@ -23,9 +21,12 @@ set(stepcore_SRCS
coulombforce.cc
spring.cc
motor.cc
joint.cc
eulersolver.cc
tool.cc
joints.cc
solver.cc
eulersolver.cc
collisionsolver.cc
constraintsolver.cc
xmlfile.cc
)
......
This diff is collapsed.
/* This file is part of StepCore library.
Copyright (C) 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
Copyright (C) 2014 Inge Wallin <inge@lysator.liu.se>
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
......@@ -17,192 +18,102 @@
*/
/** \file joint.h
* \brief Joint classes
* \brief Contains the Joint object.
*/
#ifndef STEPCORE_JOINT_H
#define STEPCORE_JOINT_H
#include "world.h"
#include <vector> // XXX: Replace if Qt is enabled.
#include "types.h"
#include "item.h"
namespace StepCore
{
class Particle;
class RigidBody;
/** \ingroup joints
* \brief Fixes position of the body
* Constraints information structure
* XXX: Move it to constraintsolver.h
*/
class Anchor: public Item, public Joint
struct ConstraintsInfo
{
STEPCORE_OBJECT(Anchor)
public:
/** Constructs Anchor */
explicit Anchor(Object* body = 0, const Vector2d& position = Vector2d::Zero(), double angle = 0);
int variablesCount; ///< Number of dynamic variables
int constraintsCount; ///< Number of constraints equations
int contactsCount; ///< Number of additional constrains
///< equations due to contacts
/** Get pointer to the body */
Object* body() const { return _body; }
/** Set pointer to the body */
void setBody(Object* body);
VectorXd value; ///< Current constarints values (amount of brokenness)
VectorXd derivative; ///< Time-derivative of constraints values
DynSparseRowMatrix jacobian; ///< Position-derivative of constraints values
DynSparseRowMatrix jacobianDerivative; ///< Time-derivative of constraintsJacobian
VectorXd inverseMass; ///< Diagonal coefficients of the inverse mass matrix of the system
/** Get position of the anchor */
const Vector2d& position() const { return _position; }
/** Set position of the anchor */
void setPosition(const Vector2d& position) { _position = position; }
MappedVector position; ///< Positions of the bodies
MappedVector velocity; ///< Velocities of the bodies
MappedVector acceleration; ///< Accelerations of the bodies before applying constraints
/** Get angle of the anchor */
double angle() const { return _angle; }
/** Set angle of the anchor */
void setAngle(double angle) { _angle = angle; }
VectorXd forceMin; ///< Constraints force lower limit
VectorXd forceMax; ///< Constraints force upper limit
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
VectorXd force; ///< Resulting constraints force
//void getConstraints(double* value, double* derivative);
//void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMatrix* derivative, int offset);
bool collisionFlag; ///< True if there is a collision to be resolved
protected:
Object* _body;
Vector2d _position;
double _angle;
ConstraintsInfo(): variablesCount(0), constraintsCount(0), contactsCount(0),
position(0,0), velocity(0,0), acceleration(0,0) {}
Particle* _p;
RigidBody* _r;
};
/** Set variablesCount, constraintsCount and reset contactsCount,
* resize all arrays appropriately */
void setDimension(int newVariablesCount, int newConstraintsCount, int newContactsCount = 0);
/** \ingroup joints
* \brief Fixes position of a given point on the body
*/
class Pin: public Item, public Joint
{
STEPCORE_OBJECT(Pin)
/** Clear the structure */
void clear();
public:
/** Constructs Pin */
explicit Pin(Object* body = 0, const Vector2d& localPosition = Vector2d::Zero(),
const Vector2d& position = Vector2d::Zero());
/** Get pointer to the body */
Object* body() const { return _body; }
/** Set pointer to the body */
void setBody(Object* body);
/** Local position of the pin on the body */
const Vector2d& localPosition() const { return _localPosition; }
/** Set local position of the pin on the body */
void setLocalPosition(const Vector2d& localPosition) { _localPosition = localPosition; }
/** Get global position of the pin */
const Vector2d& position() const { return _position; }
/** Set global position of the pin */
void setPosition(const Vector2d& position) { _position = position; }
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
//void getConstraints(double* value, double* derivative);
//void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMatrix* derivative, int offset);
protected:
Object* _body;
Vector2d _localPosition;
Vector2d _position;
Particle* _p;
RigidBody* _r;
private:
ConstraintsInfo(const ConstraintsInfo&);
ConstraintsInfo& operator=(const ConstraintsInfo&);
};
/** \ingroup joints
* \brief Massless stick: fixed distance between two points on particles or rigid bodies
* \brief Interface for joints
*/
class Stick: public Item, public Joint
class Joint
{
STEPCORE_OBJECT(Stick)
STEPCORE_OBJECT(Joint)
public:
/** Constructs Stick */
explicit Stick(double restLength = 1,
Object* body1 = 0, Object* body2 = 0,
const Vector2d& localPosition1 = Vector2d::Zero(),
const Vector2d& localPosition2 = Vector2d::Zero());
/** Get the restLength of the stick */
double restLength() const { return _restLength; }
/** Set the restLength of the stick */
void setRestLength(double restLength) { _restLength = restLength; }
/** Get pointer to the first connected body */
Object* body1() const { return _body1; }
/** Set pointer to the first connected body */
void setBody1(Object* body1);
/** Get pointer to the second connected body */
Object* body2() const { return _body2; }
/** Set pointer to the second connected body */
void setBody2(Object* body2);
/** Local position of the first end of the stick on the body
* or in the world (if the end is not connected) */
Vector2d localPosition1() const { return _localPosition1; }
/** Set local position of the first end of the stick on the body
* or in the world (if the end is not connected) */
void setLocalPosition1(const Vector2d& localPosition1) { _localPosition1 = localPosition1; }
/** Local position of the second end of the stick on the body
* or in the world (if the end is not connected) */
Vector2d localPosition2() const { return _localPosition2; }
/** Set local position of the second end of the stick on the body
* or in the world (if the end is not connected) */
void setLocalPosition2(const Vector2d& localPosition2) { _localPosition2 = localPosition2; }
/** Position of the first end of the stick */
Vector2d position1() const;
/** Position of the second end of the stick */
Vector2d position2() const;
/** Velocity of the first end of the stick */
Vector2d velocity1() const;
/** Velocity of the second end of the stick */
Vector2d velocity2() const;
/** Get first connected Particle */
Particle* particle1() const { return _p1; }
/** Get second connected Particle */
Particle* particle2() const { return _p2; }
/** Get first connected RigidBody */
RigidBody* rigidBody1() const { return _r1; }
/** Get second connected RigidBody */
RigidBody* rigidBody2() const { return _r2; }
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
protected:
double _restLength;
Object* _body1;
Object* _body2;
Vector2d _localPosition1;
Vector2d _localPosition2;
Particle* _p1;
Particle* _p2;
RigidBody* _r1;
RigidBody* _r2;
};
virtual ~Joint() {}
/** \ingroup joints
* \brief Massless rope: maximal distance between two points on particles or rigid bodies
*/
class Rope: public Stick
{
STEPCORE_OBJECT(Rope)
/** Get count of constraints */
virtual int constraintsCount() = 0;
public:
void getConstraintsInfo(ConstraintsInfo* info, int offset);
/** Fill the part of constraints information structure starting at offset */
virtual void getConstraintsInfo(ConstraintsInfo* info, int offset) = 0;
#if 0
/** Get current constraints value (amaunt of brokenness) and its derivative */
virtual void getConstraints(double* value, double* derivative) = 0;
/** Get force limits, default is no limits at all */
virtual void getForceLimits(double* forceMin STEPCORE_UNUSED, double* forceMax STEPCORE_UNUSED) {}
/** Get constraints jacobian (space-derivatives of constraint value),
* its derivative and product of inverse mass matrix by transposed jacobian (wjt) */
virtual void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMatrix* derivative, int offset) = 0;
#endif
};
/** List of pointers to Joint */
typedef std::vector<Joint*> JointList;
} // namespace StepCore
#endif
This diff is collapsed.
/* 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 joint.h
* \brief Joint classes
*/
#ifndef STEPCORE_JOINTS_H
#define STEPCORE_JOINTS_H
#include "joint.h"
namespace StepCore
{
class Particle;
class RigidBody;
/** \ingroup joints
* \brief Fixes position of the body
*/
class Anchor: public Item, public Joint
{
STEPCORE_OBJECT(Anchor)
public:
/** Constructs Anchor */
explicit Anchor(Object* body = 0, const Vector2d& position = Vector2d::Zero(), double angle = 0);
/** Get pointer to the body */
Object* body() const { return _body; }
/** Set pointer to the body */
void setBody(Object* body);
/** Get position of the anchor */
const Vector2d& position() const { return _position; }
/** Set position of the anchor */
void setPosition(const Vector2d& position) { _position = position; }
/** Get angle of the anchor */
double angle() const { return _angle; }
/** Set angle of the anchor */
void setAngle(double angle) { _angle = angle; }
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
//void getConstraints(double* value, double* derivative);
//void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMatrix* derivative, int offset);
protected:
Object* _body;
Vector2d _position;
double _angle;
Particle* _p;
RigidBody* _r;
};
/** \ingroup joints
* \brief Fixes position of a given point on the body
*/
class Pin: public Item, public Joint
{
STEPCORE_OBJECT(Pin)
public:
/** Constructs Pin */
explicit Pin(Object* body = 0, const Vector2d& localPosition = Vector2d::Zero(),
const Vector2d& position = Vector2d::Zero());
/** Get pointer to the body */
Object* body() const { return _body; }
/** Set pointer to the body */
void setBody(Object* body);
/** Local position of the pin on the body */
const Vector2d& localPosition() const { return _localPosition; }
/** Set local position of the pin on the body */
void setLocalPosition(const Vector2d& localPosition) { _localPosition = localPosition; }
/** Get global position of the pin */
const Vector2d& position() const { return _position; }
/** Set global position of the pin */
void setPosition(const Vector2d& position) { _position = position; }
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
//void getConstraints(double* value, double* derivative);
//void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMatrix* derivative, int offset);
protected:
Object* _body;
Vector2d _localPosition;
Vector2d _position;
Particle* _p;
RigidBody* _r;
};
/** \ingroup joints
* \brief Massless stick: fixed distance between two points on particles or rigid bodies
*/
class Stick: public Item, public Joint
{
STEPCORE_OBJECT(Stick)
public:
/** Constructs Stick */
explicit Stick(double restLength = 1,
Object* body1 = 0, Object* body2 = 0,
const Vector2d& localPosition1 = Vector2d::Zero(),
const Vector2d& localPosition2 = Vector2d::Zero());
/** Get the restLength of the stick */
double restLength() const { return _restLength; }
/** Set the restLength of the stick */
void setRestLength(double restLength) { _restLength = restLength; }
/** Get pointer to the first connected body */
Object* body1() const { return _body1; }
/** Set pointer to the first connected body */
void setBody1(Object* body1);
/** Get pointer to the second connected body */
Object* body2() const { return _body2; }
/** Set pointer to the second connected body */
void setBody2(Object* body2);
/** Local position of the first end of the stick on the body
* or in the world (if the end is not connected) */
Vector2d localPosition1() const { return _localPosition1; }
/** Set local position of the first end of the stick on the body
* or in the world (if the end is not connected) */
void setLocalPosition1(const Vector2d& localPosition1) { _localPosition1 = localPosition1; }
/** Local position of the second end of the stick on the body
* or in the world (if the end is not connected) */
Vector2d localPosition2() const { return _localPosition2; }
/** Set local position of the second end of the stick on the body
* or in the world (if the end is not connected) */
void setLocalPosition2(const Vector2d& localPosition2) { _localPosition2 = localPosition2; }
/** Position of the first end of the stick */
Vector2d position1() const;
/** Position of the second end of the stick */
Vector2d position2() const;
/** Velocity of the first end of the stick */
Vector2d velocity1() const;
/** Velocity of the second end of the stick */
Vector2d velocity2() const;
/** Get first connected Particle */
Particle* particle1() const { return _p1; }
/** Get second connected Particle */
Particle* particle2() const { return _p2; }
/** Get first connected RigidBody */
RigidBody* rigidBody1() const { return _r1; }
/** Get second connected RigidBody */
RigidBody* rigidBody2() const { return _r2; }
int constraintsCount();
void getConstraintsInfo(ConstraintsInfo* info, int offset);
protected:
double _restLength;
Object* _body1;
Object* _body2;
Vector2d _localPosition1;
Vector2d _localPosition2;
Particle* _p1;
Particle* _p2;
RigidBody* _r1;
RigidBody* _r2;
};
/** \ingroup joints
* \brief Massless rope: maximal distance between two points on particles or rigid bodies
*/
class Rope: public Stick
{
STEPCORE_OBJECT(Rope)
public:
void getConstraintsInfo(ConstraintsInfo* info, int offset);
};
} // namespace StepCore
#endif
......@@ -29,7 +29,6 @@ namespace StepCore
{
STEPCORE_META_OBJECT(Joint, QT_TRANSLATE_NOOP("ObjectClass", "Joint"), QT_TR_NOOP("Joint"), MetaObject::ABSTRACT,,)
STEPCORE_META_OBJECT(Tool, QT_TRANSLATE_NOOP("ObjectClass", "Tool"), QT_TR_NOOP("Tool"), MetaObject::ABSTRACT,,)
STEPCORE_META_OBJECT(ItemGroup, QT_TRANSLATE_NOOP("ObjectClass", "ItemGroup"), QT_TR_NOOP("ItemGroup"), 0, STEPCORE_SUPER_CLASS(Item),)
......
......@@ -23,17 +23,23 @@
#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 "vector.h"
#include <vector> // XXX: replace if QT is enabled
#include <QHash>
// TODO: split this file
......@@ -48,78 +54,6 @@ class CollisionSolver;
class ConstraintSolver;
/** \ingroup joints
* Constraints information structure
* XXX: Move it to constraintsolver.h
*/
struct ConstraintsInfo
{
int variablesCount; ///< Number of dynamic variables
int constraintsCount; ///< Number of constraints equations
int contactsCount; ///< Number of additional constrains
///< equations due to contacts
VectorXd value; ///< Current constarints values (amount of brokenness)
VectorXd derivative; ///< Time-derivative of constraints values
DynSparseRowMatrix jacobian; ///< Position-derivative of constraints values
DynSparseRowMatrix jacobianDerivative; ///< Time-derivative of constraintsJacobian
VectorXd inverseMass; ///< Diagonal coefficients of the inverse mass matrix of the system
MappedVector position; ///< Positions of the bodies
MappedVector velocity; ///< Velocities of the bodies
MappedVector acceleration; ///< Accelerations of the bodies before applying constraints
VectorXd forceMin; ///< Constraints force lower limit
VectorXd forceMax; ///< Constraints force upper limit
VectorXd force; ///< Resulting constraints force
bool collisionFlag; ///< True if there is a collision to be resolved
ConstraintsInfo(): variablesCount(0), constraintsCount(0), contactsCount(0),
position(0,0), velocity(0,0), acceleration(0,0) {}
/** Set variablesCount, constraintsCount and reset contactsCount,
* resize all arrays appropriately */
void setDimension(int newVariablesCount, int newConstraintsCount, int newContactsCount = 0);
/** Clear the structure */
void clear();
private:
ConstraintsInfo(const ConstraintsInfo&);
ConstraintsInfo& operator=(const ConstraintsInfo&);
};
/** \ingroup joints
* \brief Interface for joints
*/
class Joint
{
STEPCORE_OBJECT(Joint)
public:
virtual ~Joint() {}
/** Get count of constraints */
virtual int constraintsCount() = 0;
/** Fill the part of constraints information structure starting at offset */
virtual void getConstraintsInfo(ConstraintsInfo* info, int offset) = 0;
#if 0
/** Get current constraints value (amaunt of brokenness) and its derivative */
virtual void getConstraints(double* value, double* derivative) = 0;
/** Get force limits, default is no limits at all */
virtual void getForceLimits(double* forceMin STEPCORE_UNUSED, double* forceMax STEPCORE_UNUSED) {}
/** Get constraints jacobian (space-derivatives of constraint value),
* its derivative and product of inverse mass matrix by transposed jacobian (wjt) */
virtual void getJacobian(GmmSparseRowMatrix* value, GmmSparseRowMa