summaryrefslogtreecommitdiffstats
path: root/src/mechanics/mechanicssimulation.h
blob: 19b474b3745cda0327ac5e4fa76d800e9bf3ae4a (plain)
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
/***************************************************************************
 *   Copyright (C) 2005 by David Saxton                                    *
 *   david@bluehaze.org                                                    *
 *                                                                         *
 *   This program 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.                                   *
 ***************************************************************************/

#ifndef MECHANICSSIMULATION_H
#define MECHANICSSIMULATION_H

#include <qguardedptr.h>
#include <qobject.h>
#include <qvaluelist.h>

class MechanicsItem;
class MechanicsDocument;
typedef QValueList<MechanicsItem*> MechanicsItemList;


/**
@short 2 dimensional vector with associated length functions et al
@author David Saxton
*/
class Vector2D
{
public:
	Vector2D();
	
	double length() const;
	double lengthSquared() const { return x*x + y*y; }
	
	double x;
	double y;
};


/**
@short State of a rigid body, in an inertial MechanicsDocument frame
@author David Saxton
*/
class RigidBodyState
{
public:
	RigidBodyState();
	
	Vector2D linearMomentum;
	double angularMomentum;
	Vector2D position; // Position of center of mass
};
		

/**
@author David Saxton
*/
class MechanicsSimulation : public QObject
{
Q_OBJECT
public:
    MechanicsSimulation( MechanicsDocument *mechanicsDocument );
    ~MechanicsSimulation();
	
	MechanicsDocument* mechanicsDocument() const { return p_mechanicsDocument; }

protected slots:
	void slotAdvance();
	
protected:
	QGuardedPtr<MechanicsDocument> p_mechanicsDocument;
	QTimer *m_advanceTmr;
};


/**
Rigid body with mass, inertia, etc. Collection of mechanics items with
functionality for moving them about, rotating, etc. Only one mother-parent
(has no parent itself, all other items are descendents) allowed.
@short Rigid body, handles MechanicsItems
@author David Saxton
*/
class RigidBody
{
public:
	RigidBody( MechanicsDocument *mechanicsDocument );
	~RigidBody();
	
	/**
	 * 
	 */
	void advance( int phase, double delta );
	/**
	 * Add the MechanicsItem to the entity.
	 * @returns true iff successful in adding
	 */
	bool addMechanicsItem( MechanicsItem *item );
	/**
	 * Pointer to the mother MechanicsItem.
	 */
	MechanicsItem *overallParent() const { return p_overallParent; }
	/**
	 * Updates the mass and the moment of inertia info
	 */
	void updateRigidBodyInfo();
	
protected:
	/**
	 * Attempt to find the overall parent.
	 * @returns false iff unsucessful (including if there are no MechanicsItems present)
	 */
	bool findOverallParent();
	/**
	 * Move the set of MechanicsItems by the given amount
	 */
	void moveBy( double dx, double dy );
	/**
	 * Rotate the set of MechanicsItems by the given amount about the center of
	 * mass.
	 * @param angle Rotate amount in radians
	 */
	void rotateBy( double dtheta );
	
	MechanicsItemList m_mechanicsItemList;
	MechanicsItem *p_overallParent;
	MechanicsDocument *p_mechanicsDocument;
	
	RigidBodyState m_rigidBodyState;
	double m_mass;
	double m_momentOfInertia;
};

#endif