Class: BulldogPhysics::RigidBody

Inherits:
Object
  • Object
show all
Defined in:
lib/RigidBodies/rigid_body.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRigidBody

Returns a new instance of RigidBody.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/RigidBodies/rigid_body.rb', line 26

def initialize()
	@inverse_mass = 0
	@mass = 1
	@linear_damping , @angular_damping = 0.9, 0.9
	@acceleration = Vector3.new
	@position  = Vector3.new
	@velocity = Vector3.new
	@orientation = Quaternion.new
	@transform_matrix = Matrix4.new
	@rotation = Vector3.new
	@inverse_inertia_tensor = Matrix3.new
	@inverse_inertia_tensor_world = Matrix3.new
	@torque_accum = Vector3.new
	@force_accum = Vector3.new
	@material = Material.new
	@last_frame_acceleration = Vector3.new
	@motion = 0.0
	@sleep_epsilon = 0.5
end

Instance Attribute Details

#accelerationObject

Returns the value of attribute acceleration.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def acceleration
  @acceleration
end

#angular_dampingObject

Returns the value of attribute angular_damping.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def angular_damping
  @angular_damping
end

#force_accumObject

Returns the value of attribute force_accum.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def force_accum
  @force_accum
end

#frozenObject

Returns the value of attribute frozen.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def frozen
  @frozen
end

#inverse_inertia_tensorObject (readonly)

Holds the inverse of the body’s inertia tensor. The intertia tensor provided must not be degenerate (that would mean the body had zero inertia for spinning along one axis). As long as the tensor is finite, it will be invertible. The inverse tensor is used for similar reasons to the use of inverse * mass.

The inertia tensor, unlike the other variables that define a rigid body, is given in body space.



21
22
23
# File 'lib/RigidBodies/rigid_body.rb', line 21

def inverse_inertia_tensor
  @inverse_inertia_tensor
end

#inverse_inertia_tensor_worldObject

Returns the value of attribute inverse_inertia_tensor_world.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def inverse_inertia_tensor_world
  @inverse_inertia_tensor_world
end

#inverse_massObject

Returns the value of attribute inverse_mass.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def inverse_mass
  @inverse_mass
end

#is_awakeObject

Returns the value of attribute is_awake.



11
12
13
# File 'lib/RigidBodies/rigid_body.rb', line 11

def is_awake
  @is_awake
end

#last_frame_accelerationObject

Returns the value of attribute last_frame_acceleration.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def last_frame_acceleration
  @last_frame_acceleration
end

#linear_dampingObject

Returns the value of attribute linear_damping.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def linear_damping
  @linear_damping
end

#massObject

Returns the value of attribute mass.



9
10
11
# File 'lib/RigidBodies/rigid_body.rb', line 9

def mass
  @mass
end

#materialObject

Returns the value of attribute material.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def material
  @material
end

#motionObject

Returns the value of attribute motion.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def motion
  @motion
end

#orientationObject

Returns the value of attribute orientation.



11
12
13
# File 'lib/RigidBodies/rigid_body.rb', line 11

def orientation
  @orientation
end

#positionObject

Returns the value of attribute position.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def position
  @position
end

#rotationObject

Returns the value of attribute rotation.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def rotation
  @rotation
end

#sleep_epsilonObject

Returns the value of attribute sleep_epsilon.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def sleep_epsilon
  @sleep_epsilon
end

#torque_accumObject

Returns the value of attribute torque_accum.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def torque_accum
  @torque_accum
end

#transform_matrixObject

Returns the value of attribute transform_matrix.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def transform_matrix
  @transform_matrix
end

#velocityObject

Returns the value of attribute velocity.



6
7
8
# File 'lib/RigidBodies/rigid_body.rb', line 6

def velocity
  @velocity
end

Class Method Details

.calculate_transform_matrix(transformMatrix, position, orientation) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/RigidBodies/rigid_body.rb', line 198

def self.calculate_transform_matrix(transformMatrix, position, orientation)
	transformMatrix.data[0] = 1-2*orientation.j*orientation.j -
							2*orientation.k*orientation.k; 
	transformMatrix.data[1] = 2*orientation.i*orientation.j -
							2*orientation.r*orientation.k; 
	transformMatrix.data[2] = 2*orientation.i*orientation.k +
							 2*orientation.r*orientation.j; 
	transformMatrix.data[3] = position.x;

	transformMatrix.data[4] = 2*orientation.i*orientation.j + 
							  2*orientation.r*orientation.k;
	transformMatrix.data[5] = 1-2*orientation.i*orientation.i - 
								2*orientation.k*orientation.k;
	transformMatrix.data[6] = 2*orientation.j*orientation.k - 
							  2*orientation.r*orientation.i;
	transformMatrix.data[7] = position.y;
	transformMatrix.data[8] = 2*orientation.i*orientation.k - 
							  2*orientation.r*orientation.j;
	transformMatrix.data[9] = 2*orientation.j*orientation.k + 
	2*orientation.r*orientation.i;
	transformMatrix.data[10] = 1-2*orientation.i*orientation.i - 
								2*orientation.j*orientation.j;
	transformMatrix.data[11] = position.z;
end

.transform_inertia_tensor(iitWorld, q, iitBody, rotmat) ⇒ Object

Internal function to do an intertia tensor transform by a quaternion. Note that the implementation of this function was created by an automated code generator and optimizer.



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
# File 'lib/RigidBodies/rigid_body.rb', line 154

def self.transform_inertia_tensor(iitWorld, q, iitBody, rotmat )
	 t4 = rotmat.data[0]*iitBody.data[0]+
	rotmat.data[1]*iitBody.data[3]+
	rotmat.data[2]*iitBody.data[6];
	 t9 = rotmat.data[0]*iitBody.data[1]+
	rotmat.data[1]*iitBody.data[4]+
	rotmat.data[2]*iitBody.data[7];
	 t14 = rotmat.data[0]*iitBody.data[2]+
	rotmat.data[1]*iitBody.data[5]+
	rotmat.data[2]*iitBody.data[8];
	 t28 = rotmat.data[4]*iitBody.data[0]+
	rotmat.data[5]*iitBody.data[3]+
	rotmat.data[6]*iitBody.data[6];
	 t33 = rotmat.data[4]*iitBody.data[1]+
	rotmat.data[5]*iitBody.data[4]+
	rotmat.data[6]*iitBody.data[7];
	 t38 = rotmat.data[4]*iitBody.data[2]+
	rotmat.data[5]*iitBody.data[5]+
	rotmat.data[6]*iitBody.data[8];
	 t52 = rotmat.data[8]*iitBody.data[0]+
	rotmat.data[9]*iitBody.data[3]+
	rotmat.data[10]*iitBody.data[6];
	 t57 = rotmat.data[8]*iitBody.data[1]+
	rotmat.data[9]*iitBody.data[4]+
	rotmat.data[10]*iitBody.data[7];
	 t62 = rotmat.data[8]*iitBody.data[2]+
	rotmat.data[9]*iitBody.data[5]+ rotmat.data[10]*iitBody.data[8];
	iitWorld.data[0] = t4*rotmat.data[0]+ t9*rotmat.data[1]+ t14*rotmat.data[2];
	iitWorld.data[1] = t4*rotmat.data[4]+ t9*rotmat.data[5]+ t14*rotmat.data[6];
	iitWorld.data[2] = t4*rotmat.data[8]+ t9*rotmat.data[9]+ t14*rotmat.data[10];
	iitWorld.data[3] = t28*rotmat.data[0]+ t33*rotmat.data[1]+
	t38*rotmat.data[2]; iitWorld.data[4] = t28*rotmat.data[4]+
	t33*rotmat.data[5]+
	t38*rotmat.data[6]; iitWorld.data[5] = t28*rotmat.data[8]+
	t33*rotmat.data[9]+
	t38*rotmat.data[10]; iitWorld.data[6] = t52*rotmat.data[0]+
	t57*rotmat.data[1]+
	t62*rotmat.data[2]; iitWorld.data[7] = t52*rotmat.data[4]+
	t57*rotmat.data[5]+
	t62*rotmat.data[6]; iitWorld.data[8] = t52*rotmat.data[8]+
	t57*rotmat.data[9]+ t62*rotmat.data[10];

end

Instance Method Details

#add_force(force) ⇒ Object

Adds the given force to center of mass of the rigid body The force is expressed in world coordinates.



83
84
85
86
# File 'lib/RigidBodies/rigid_body.rb', line 83

def add_force(force)
	@force_accum.addVector(force)
	self.is_awake = true
end

#add_force_at_body_point(force, point) ⇒ Object



138
139
140
141
142
# File 'lib/RigidBodies/rigid_body.rb', line 138

def add_force_at_body_point(force, point)
	pt = get_point_in_world_space(point)
	add_force_at_point(force, pt)
	@is_awake = true
end

#add_force_at_point(force, point) ⇒ Object



144
145
146
147
148
149
150
# File 'lib/RigidBodies/rigid_body.rb', line 144

def add_force_at_point(force, point)
	pt = point
	pt -= @position
	@force_accum += force
	@torque_accum += pt % force
	@is_awake = true
end

#calculate_derived_dataObject

Calculates internal data from state data. This should be called * after the body’s state is altered directly (it is called automatically during integration). If you change the body’s state * and then intend to integrate before querying any data (such as the transform matrix), then you can omit this step.



70
71
72
73
74
75
# File 'lib/RigidBodies/rigid_body.rb', line 70

def calculate_derived_data
	@orientation.normalize()
	RigidBody.calculate_transform_matrix(@transform_matrix, @position, @orientation)
	RigidBody.transform_inertia_tensor(@inverse_inertia_tensor_world,
		@orientation, @inverse_inertia_tensor, @transform_matrix);
end

#clear_accumulatorsObject



133
134
135
136
# File 'lib/RigidBodies/rigid_body.rb', line 133

def clear_accumulators()
	@force_accum.clear
	@torque_accum.clear
end

#get_gl_transformObject



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/RigidBodies/rigid_body.rb', line 232

def get_gl_transform()
	matrix = Array.new(16)
 matrix[0] = @transform_matrix.data[0];
 matrix[1] = @transform_matrix.data[4];
 matrix[2] = @transform_matrix.data[8];
 matrix[3] = 0;

 matrix[4] = @transform_matrix.data[1];
 matrix[5] = @transform_matrix.data[5];
 matrix[6] = @transform_matrix.data[9];
 matrix[7] = 0;

 matrix[8] = @transform_matrix.data[2];
 matrix[9] = @transform_matrix.data[6];
 matrix[10] = @transform_matrix.data[10];
 matrix[11] = 0;

 matrix[12] = @transform_matrix.data[3];
 matrix[13] = @transform_matrix.data[7];
 matrix[14] = @transform_matrix.data[11];
 matrix[15] = 1;

 matrix
end

#get_point_in_local_space(point) ⇒ Object



224
225
226
# File 'lib/RigidBodies/rigid_body.rb', line 224

def get_point_in_local_space(point)
	@transform_matrix.transformInverse(point);
end

#get_point_in_world_space(point) ⇒ Object



228
229
230
# File 'lib/RigidBodies/rigid_body.rb', line 228

def get_point_in_world_space(point)
	@transform_matrix.transform(point);
end

#hasFiniteMassObject



88
89
90
# File 'lib/RigidBodies/rigid_body.rb', line 88

def hasFiniteMass
	return @mass < 0.0
end

#integrate(duration) ⇒ Object



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
# File 'lib/RigidBodies/rigid_body.rb', line 93

def integrate(duration)

	return if !@is_awake
	
	@last_frame_acceleration = @acceleration.dup
	@last_frame_acceleration.addScaledVector(@force_accum, @inverse_mass)

	angular_acceleration = @inverse_inertia_tensor_world.transform(@torque_accum)

	@velocity.addScaledVector( @last_frame_acceleration, duration)
	@rotation.addScaledVector(angular_acceleration, duration)

	@velocity *= @linear_damping ** duration
	@rotation *= @angular_damping ** duration

	#$@rotation *= @angular_damping ** duration
	#@velocity.multiplyByScalar( @linear_damping ** duration)
	@position.addScaledVector(@velocity, duration)
	@orientation.addScaledVector(@rotation, duration)

	calculate_derived_data()

	clear_accumulators()

	@can_sleep ||= true
=begin
	if can_sleep
		current_motion = @velocity.scalarProduct(@velocity) + @rotation.scalarProduct(@rotation) 
		bias = 0.5 ** duration
		@motion = (bias * @motion) + ((1-@bias)*current_motion)

		if motion < @sleep_epsilon
			self.is_awake=false
		elsif @motion > 10 * @sleep_epsilon
			@motion = 10 * @sleep_epsilon
		end
	end
=end
end

#set_inertia_tensor(inertia_tensor) ⇒ Object



78
79
80
# File 'lib/RigidBodies/rigid_body.rb', line 78

def set_inertia_tensor(inertia_tensor)
	@inverse_inertia_tensor.setInverse(inertia_tensor)
end