RigidObject.cpp 3.99 KB
Newer Older
Yuwei Xiao's avatar
init  
Yuwei Xiao committed
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
#include "RigidObject.h"

RigidObject::RigidObject(const std::string& mesh_file, const ObjType t) {
	findAndLoadMesh(mesh_file);
	setType(t);
	setMass(1.0);

	// inertia of cube
	setInertia(getMass() * 2.0 / 6.0 * Eigen::Matrix3d::Identity());
	reset();
}

void RigidObject::resetMembers() {
	setLinearMomentum(Eigen::Vector3d::Zero());
	setAngularMomentum(Eigen::Vector3d::Zero());
	resetForce();
	resetTorque();
}

void RigidObject::applyForceToCOM(const Eigen::Vector3d& f) {
	if (m_type != ObjType::DYNAMIC) return;

	m_force += f;
}

void RigidObject::applyForce(const Eigen::Vector3d& f,
	const Eigen::Vector3d& p) {
	if (m_type != ObjType::DYNAMIC) return;

	m_force += f;
	m_torque += (p - m_position).cross(f);
}

void RigidObject::applyTorque(const Eigen::Vector3d& t) {
	if (m_type != ObjType::DYNAMIC) return;

	m_torque += t;
}

void RigidObject::printDebug(const std::string& message) const {
	std::cout << std::endl;
	if (message.size() > 0) {
		std::cout << message << std::endl;
	}
	std::cout << "position:         " << m_position.transpose() << std::endl;
	std::cout << "rotation:         " << std::endl << m_rot << std::endl;
	std::cout << "linear velocity:  " << m_v.transpose() << std::endl;
	std::cout << "angular velocity: " << m_w.transpose() << std::endl;
	std::cout << "force:            " << m_force.transpose() << std::endl;
	std::cout << "torque:           " << m_torque.transpose() << std::endl;
	std::cout << "mass (inv):           " << m_mass << " (" << m_massInv << ")"
		<< std::endl;
}

#pragma region GettersAndSetters
void RigidObject::setType(ObjType t) {
	m_type = t;

	if (m_type == ObjType::STATIC) {
		m_mass = std::numeric_limits<double>::infinity();
		m_massInv = 0.0;
		m_inertia.setZero();
		m_inertiaInv.setZero();
		m_force.setZero();
		m_torque.setZero();
	}
}

void RigidObject::setMass(double m) {
	if (m_type != ObjType::DYNAMIC) return;
	m_mass = m;
	m_massInv = 1.0 / m_mass;
}

void RigidObject::setInertia(const Eigen::Matrix3d& I) {
	if (m_type != ObjType::DYNAMIC) return;

	m_inertia = I;
	m_inertiaInv = m_inertia.inverse();
}

void RigidObject::setLinearMomentum(const Eigen::Vector3d& p) {
	if (m_type != ObjType::DYNAMIC) return;

	m_v = m_massInv * p;
}

void RigidObject::setAngularMomentum(const Eigen::Vector3d& l) {
	if (m_type != ObjType::DYNAMIC) return;

	m_w = getInertiaInvWorld() * l;
}

void RigidObject::setLinearVelocity(const Eigen::Vector3d& v) {
	if (m_type != ObjType::DYNAMIC) return;

	m_v = v;
}

void RigidObject::setAngularVelocity(const Eigen::Vector3d& w) {
	if (m_type != ObjType::DYNAMIC) return;

	m_w = w;
}

void RigidObject::setForce(const Eigen::Vector3d& f) {
	if (m_type != ObjType::DYNAMIC) return;

	m_force = f;
}

void RigidObject::setTorque(const Eigen::Vector3d& t) {
	if (m_type != ObjType::DYNAMIC) return;

	m_torque = t;
}

void RigidObject::resetForce() { m_force.setZero(); };

void RigidObject::resetTorque() { m_torque.setZero(); };

double RigidObject::getMass() const { return m_mass; }

double RigidObject::getMassInv() const { return m_massInv; }

Eigen::Matrix3d RigidObject::getInertia() const { return m_inertia; }

Eigen::Matrix3d RigidObject::getInertiaInv() const { return m_inertiaInv; }

Eigen::Matrix3d RigidObject::getInertiaInvWorld() const {
	return m_quat * m_inertiaInv * m_quat.inverse();
}

Eigen::Matrix3d RigidObject::getInertiaWorld() const {
	return m_quat * m_inertia * m_quat.inverse();
}

Eigen::Vector3d RigidObject::getLinearMomentum() const { return m_v * m_mass; }

Eigen::Vector3d RigidObject::getAngularMomentum() const {
	return getInertiaWorld() * m_w;
}

Eigen::Vector3d RigidObject::getLinearVelocity() const { return m_v; }

Eigen::Vector3d RigidObject::getVelocity(const Eigen::Vector3d& point) const {
	return getLinearVelocity() +
		getAngularVelocity().cross(point - getPosition());
}

Eigen::Vector3d RigidObject::getAngularVelocity() const { return m_w; }

Eigen::Vector3d RigidObject::getForce() const { return m_force; }

Eigen::Vector3d RigidObject::getTorque() const { return m_torque; }

#pragma endregion GettersAndSetters