Class: BulldogPhysics::ContactResolver

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(iterations, velocity_epsilon = 0.01, position_epsilon = 0.01) ⇒ ContactResolver

Returns a new instance of ContactResolver.



13
14
15
16
# File 'lib/RigidBodies/contact_resolver.rb', line 13

def initialize(iterations, velocity_epsilon = 0.01, position_epsilon = 0.01)
	set_iterations(iterations, iterations)
	set_epsilon(velocity_epsilon, position_epsilon)
end

Instance Attribute Details

#position_iterations_usedObject

Returns the value of attribute position_iterations_used.



8
9
10
# File 'lib/RigidBodies/contact_resolver.rb', line 8

def position_iterations_used
  @position_iterations_used
end

#valid_settingsObject (readonly)

Returns the value of attribute valid_settings.



10
11
12
# File 'lib/RigidBodies/contact_resolver.rb', line 10

def valid_settings
  @valid_settings
end

#velocity_epsilonObject (readonly)

Returns the value of attribute velocity_epsilon.



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

def velocity_epsilon
  @velocity_epsilon
end

#velocity_iterationsObject (readonly)

Returns the value of attribute velocity_iterations.



4
5
6
# File 'lib/RigidBodies/contact_resolver.rb', line 4

def velocity_iterations
  @velocity_iterations
end

#velocity_iterations_usedObject

Returns the value of attribute velocity_iterations_used.



8
9
10
# File 'lib/RigidBodies/contact_resolver.rb', line 8

def velocity_iterations_used
  @velocity_iterations_used
end

Instance Method Details

#adjust_positions(c, num_contacts, duration) ⇒ Object

c is a contact array



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

def adjust_positions(c, num_contacts, duration)
	linearChange = [Vector3.new, Vector3.new]
	angularChange = [Vector3.new, Vector3.new]
	#angularChange = Vector3.new
	deltaPosition = Vector3.new

	@position_iterations_used = 0
	while @position_iterations_used < @position_iterations

		max = @position_epsilon
		index = num_contacts

		for i in 0..num_contacts
			if( c[i].penetration > max)
				max = c[i].penetration
				puts "MAX #{max}"
				index = i
			end
		end

		break if (index == num_contacts)

		c[index].match_awake_state
		c[index].apply_position_change( linearChange, angularChange, max)

		for i in 0..num_contacts-1
			for b in 0..1
				#next if c[i].body[b].nil?

				for d in 0..1

					if(c[i].body[b] == c[index].body[d])
						deltaPosition = linearChange[d] + angularChange[d].vector_product( c[i].relative_contact_position[b])
						test = b == 1 ? 1 : -1 
						#puts test
						c[i].penetration += deltaPosition.scalarProduct(c[i].contact_normal) * test
					end
				end
			end
		end
		@position_iterations_used += 1
	end
end

#adjust_velocities(contact_array, num_contacts, duration) ⇒ Object



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

def adjust_velocities(contact_array, num_contacts, duration)
	velocityChange = [Vector3.new, Vector3.new]
	rotationChange = [Vector3.new, Vector3.new]
	deltaVel = Vector3.new

	@velocity_iterations_used = 0

	while @velocity_iterations_used < @velocity_iterations do

		max = @velocity_epsilon
		index = num_contacts
		for i in 0..num_contacts-1
			if(contact_array[i].desired_delta_velocity > max)
				max = contact_array[i].desired_delta_velocity
				index = i
			end
		end

		break if index == num_contacts

		contact_array[index].match_awake_state
		contact_array[index].apply_velocity_change(velocityChange, rotationChange)

		for i in i..num_contacts-1
			for b in 0..1
				next if contact_array[i].body[b].nil?
				for d in 0..1
					if(contact_array[i].body[b] == contact_array[index].body[d])
						deltaVel = velocityChange[d] + rotationChange[d].vector_product(contact_array[i].relative_contact_position[b]);
						#puts "DELAT VEL #{deltaVel}"
						#puts "CONTACT VELOCITY #{contact_array[i].contact_velocity}"
						#puts "CONTACT TO WORLD "

						change = contact_array[i].contact_to_world.transformTranspose(deltaVel) 
						if(b)
							contact_array[i].contact_velocity -= change
						else
							contact_array[i].contact_velocity += change
						end

						contact_array[i].calculate_desired_delta_velocity(duration)
					end
				end
			end
		end
		@velocity_iterations_used += 1
	end

end

#is_validObject



18
19
20
# File 'lib/RigidBodies/contact_resolver.rb', line 18

def is_valid
	@velocity_iterations > 0 && @position_iterations > 0 && @position_epsilon >= 0.0 && @velocity_epsilon >= 0
end

#prepare_contacts(contact_array, num_contacts, duration) ⇒ Object



41
42
43
44
45
# File 'lib/RigidBodies/contact_resolver.rb', line 41

def prepare_contacts(contact_array, num_contacts, duration)
	contact_array.each do |contact|
		contact.calculate_internals(duration)
	end
end

#resolve_contacts(contact_array, num_contacts, duration) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/RigidBodies/contact_resolver.rb', line 32

def resolve_contacts(contact_array, num_contacts, duration)
	return if num_contacts == 0
	return unless is_valid

	prepare_contacts(contact_array, num_contacts, duration)
	adjust_positions(contact_array, num_contacts, duration)
	adjust_velocities(contact_array, num_contacts, duration)
end

#set_epsilon(velocity_epsilon, position_epsilon) ⇒ Object



27
28
29
30
# File 'lib/RigidBodies/contact_resolver.rb', line 27

def set_epsilon(velocity_epsilon, position_epsilon)
	@velocity_epsilon = velocity_epsilon
	@position_epsilon = position_epsilon
end

#set_iterations(velocity_iterations, position_iterations) ⇒ Object



22
23
24
25
# File 'lib/RigidBodies/contact_resolver.rb', line 22

def set_iterations(velocity_iterations, position_iterations)
	@velocity_iterations = velocity_iterations
	@position_iterations = position_iterations
end