bulldog_physics 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +25 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bulldog_physics.gemspec +92 -0
- data/lib/Particles/particle.rb +75 -0
- data/lib/Particles/particle_anchored_spring.rb +42 -0
- data/lib/Particles/particle_cable.rb +52 -0
- data/lib/Particles/particle_contact.rb +121 -0
- data/lib/Particles/particle_contact_generator.rb +28 -0
- data/lib/Particles/particle_contact_resolver.rb +49 -0
- data/lib/Particles/particle_drag.rb +30 -0
- data/lib/Particles/particle_force_generator.rb +23 -0
- data/lib/Particles/particle_force_registration.rb +15 -0
- data/lib/Particles/particle_force_registry.rb +50 -0
- data/lib/Particles/particle_gravity.rb +31 -0
- data/lib/Particles/particle_ground_contacts.rb +43 -0
- data/lib/Particles/particle_link.rb +41 -0
- data/lib/Particles/particle_particle_contacts.rb +48 -0
- data/lib/Particles/particle_rod.rb +58 -0
- data/lib/Particles/particle_spring.rb +44 -0
- data/lib/Particles/particle_world.rb +116 -0
- data/lib/Particles/projectile.rb +15 -0
- data/lib/bulldog_physics.rb +43 -0
- data/lib/examples/GlStuff/gl_utility.rb +21 -0
- data/lib/examples/GlStuff/lighting.rb +35 -0
- data/lib/examples/GlStuff/material.rb +24 -0
- data/lib/examples/GlStuff/terrain.rb +216 -0
- data/lib/examples/simple_game.rb +289 -0
- data/lib/matrix3.rb +242 -0
- data/lib/matrix4.rb +230 -0
- data/lib/quaternion.rb +86 -0
- data/lib/vector3.rb +155 -0
- data/test/helper.rb +18 -0
- data/test/test_bulldog_physics.rb +7 -0
- metadata +190 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem 'require_all'
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.6.4"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
git (1.2.5)
|
5
|
+
jeweler (1.6.4)
|
6
|
+
bundler (~> 1.0)
|
7
|
+
git (>= 1.2.5)
|
8
|
+
rake
|
9
|
+
rake (0.9.2.2)
|
10
|
+
rcov (0.9.11)
|
11
|
+
require_all (1.2.1)
|
12
|
+
shoulda (2.11.3)
|
13
|
+
|
14
|
+
PLATFORMS
|
15
|
+
ruby
|
16
|
+
|
17
|
+
DEPENDENCIES
|
18
|
+
bundler (~> 1.0.0)
|
19
|
+
jeweler (~> 1.6.4)
|
20
|
+
rcov
|
21
|
+
require_all
|
22
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Conner Wingard
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
= bulldog_physics
|
2
|
+
|
3
|
+
bulldog_physics started as a school project at Champlain College. It has been put together from
|
4
|
+
code samples provided in the book "Game Physics Engine Development : How to Build a Robust Commercial-Grade Physics Engine for your game" by Ian Millington. As the code samples in the book were in C++,
|
5
|
+
all of it had to be converted. As such, a lot of it still looks C like.
|
6
|
+
|
7
|
+
There is an example showing some of the things that the engine can do, gravity, bouncing of planes, being connected via springs (of various types) . Many more effects can be added by merely by subclassing one of the ForceGenerators.
|
8
|
+
|
9
|
+
Documentation will be created as soon as time allows for me to do so.
|
10
|
+
|
11
|
+
== Contributing to bulldog_physics
|
12
|
+
|
13
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
14
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
15
|
+
* Fork the project
|
16
|
+
* Start a feature/bugfix branch
|
17
|
+
* Commit and push until you are happy with your contribution
|
18
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
19
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
20
|
+
|
21
|
+
== Copyright
|
22
|
+
|
23
|
+
Copyright (c) 2012 Conner Wingard. See LICENSE.txt for
|
24
|
+
further details.
|
25
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "bulldog_physics"
|
18
|
+
gem.homepage = "http://github.com/ConnerMan/bulldog_physics"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{A 3D Physics Engine in Ruby}
|
21
|
+
gem.description = %Q{3D Physics Engine written in pure ruby that can be used for creating 3d simulations or games}
|
22
|
+
gem.email = "conner.wingard@gmail.com"
|
23
|
+
gem.authors = ["Conner Wingard"]
|
24
|
+
|
25
|
+
gem.add_dependency 'require_all'
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
Rake::TestTask.new(:test) do |test|
|
32
|
+
test.libs << 'lib' << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
|
37
|
+
require 'rcov/rcovtask'
|
38
|
+
Rcov::RcovTask.new do |test|
|
39
|
+
test.libs << 'test'
|
40
|
+
test.pattern = 'test/**/test_*.rb'
|
41
|
+
test.verbose = true
|
42
|
+
test.rcov_opts << '--exclude "gems/*"'
|
43
|
+
end
|
44
|
+
|
45
|
+
task :default => :test
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "bulldog_physics #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "bulldog_physics"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Conner Wingard"]
|
12
|
+
s.date = "2012-04-24"
|
13
|
+
s.description = "3D Physics Engine written in pure ruby that can be used for creating 3d simulations or games"
|
14
|
+
s.email = "conner.wingard@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"bulldog_physics.gemspec",
|
28
|
+
"lib/Particles/particle.rb",
|
29
|
+
"lib/Particles/particle_anchored_spring.rb",
|
30
|
+
"lib/Particles/particle_cable.rb",
|
31
|
+
"lib/Particles/particle_contact.rb",
|
32
|
+
"lib/Particles/particle_contact_generator.rb",
|
33
|
+
"lib/Particles/particle_contact_resolver.rb",
|
34
|
+
"lib/Particles/particle_drag.rb",
|
35
|
+
"lib/Particles/particle_force_generator.rb",
|
36
|
+
"lib/Particles/particle_force_registration.rb",
|
37
|
+
"lib/Particles/particle_force_registry.rb",
|
38
|
+
"lib/Particles/particle_gravity.rb",
|
39
|
+
"lib/Particles/particle_ground_contacts.rb",
|
40
|
+
"lib/Particles/particle_link.rb",
|
41
|
+
"lib/Particles/particle_particle_contacts.rb",
|
42
|
+
"lib/Particles/particle_rod.rb",
|
43
|
+
"lib/Particles/particle_spring.rb",
|
44
|
+
"lib/Particles/particle_world.rb",
|
45
|
+
"lib/Particles/projectile.rb",
|
46
|
+
"lib/bulldog_physics.rb",
|
47
|
+
"lib/examples/GlStuff/gl_utility.rb",
|
48
|
+
"lib/examples/GlStuff/lighting.rb",
|
49
|
+
"lib/examples/GlStuff/material.rb",
|
50
|
+
"lib/examples/GlStuff/terrain.rb",
|
51
|
+
"lib/examples/simple_game.rb",
|
52
|
+
"lib/matrix3.rb",
|
53
|
+
"lib/matrix4.rb",
|
54
|
+
"lib/quaternion.rb",
|
55
|
+
"lib/vector3.rb",
|
56
|
+
"test/helper.rb",
|
57
|
+
"test/test_bulldog_physics.rb"
|
58
|
+
]
|
59
|
+
s.homepage = "http://github.com/ConnerMan/bulldog_physics"
|
60
|
+
s.licenses = ["MIT"]
|
61
|
+
s.require_paths = ["lib"]
|
62
|
+
s.rubygems_version = "1.8.13"
|
63
|
+
s.summary = "A 3D Physics Engine in Ruby"
|
64
|
+
|
65
|
+
if s.respond_to? :specification_version then
|
66
|
+
s.specification_version = 3
|
67
|
+
|
68
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
69
|
+
s.add_runtime_dependency(%q<require_all>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
71
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
73
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
74
|
+
s.add_runtime_dependency(%q<require_all>, [">= 0"])
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<require_all>, [">= 0"])
|
77
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
78
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
79
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
80
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
81
|
+
s.add_dependency(%q<require_all>, [">= 0"])
|
82
|
+
end
|
83
|
+
else
|
84
|
+
s.add_dependency(%q<require_all>, [">= 0"])
|
85
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
86
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
87
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
88
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
89
|
+
s.add_dependency(%q<require_all>, [">= 0"])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
module Particles
|
3
|
+
|
4
|
+
class Particle
|
5
|
+
|
6
|
+
attr_accessor :position, :velocity, :acceleration, :damping, :force_accum, :mass, :material, :radius, :frozen
|
7
|
+
|
8
|
+
|
9
|
+
def initialize()
|
10
|
+
@position = Vector3.new
|
11
|
+
@velocity = Vector3.new
|
12
|
+
@acceleration = Vector3.new
|
13
|
+
@force_accum = Vector3.new
|
14
|
+
@mass = 0
|
15
|
+
@damping = 0.0
|
16
|
+
@material = Material.new
|
17
|
+
@radius = 0.5
|
18
|
+
@frozen = false
|
19
|
+
end
|
20
|
+
|
21
|
+
def inverse_mass
|
22
|
+
if @mass.eql? 0
|
23
|
+
return 0
|
24
|
+
else
|
25
|
+
return 1.0 / @mass
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def integrate(duration)
|
31
|
+
|
32
|
+
if @frozen
|
33
|
+
clearAccumulator
|
34
|
+
return
|
35
|
+
end
|
36
|
+
if(inverse_mass <= 0.0)
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
if(duration < 0.0)
|
41
|
+
raise Exception.new
|
42
|
+
end
|
43
|
+
|
44
|
+
@position.addScaledVector(@velocity, duration)
|
45
|
+
|
46
|
+
resulting_acc = @acceleration.dup
|
47
|
+
resulting_acc.addScaledVector(@force_accum, inverse_mass)
|
48
|
+
|
49
|
+
@velocity.addScaledVector(resulting_acc, duration)
|
50
|
+
|
51
|
+
unless @damping == 0.0
|
52
|
+
modifier = @damping ** duration
|
53
|
+
@velocity.multiplyByScalar( modifier )
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
clearAccumulator
|
58
|
+
end
|
59
|
+
|
60
|
+
def addForce(forceVector3)
|
61
|
+
@force_accum.addVector( forceVector3 )
|
62
|
+
end
|
63
|
+
|
64
|
+
def clearAccumulator
|
65
|
+
@force_accum.clear();
|
66
|
+
end
|
67
|
+
|
68
|
+
def has_infinite_mass
|
69
|
+
@mass < 0
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
module Particles
|
3
|
+
module Generators
|
4
|
+
|
5
|
+
class ParticleAnchoredSpring < ParticleForceGenerator
|
6
|
+
|
7
|
+
attr_accessor :anchor # location of the anchored end of the spring
|
8
|
+
attr_accessor :spring_constant
|
9
|
+
attr_accessor :rest_length # rest length of the string
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(anchor, spring_const, rest_len)
|
13
|
+
@anchor = anchor
|
14
|
+
@spring_constant = spring_const
|
15
|
+
@rest_length = rest_len
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_force(particle, duration)
|
19
|
+
|
20
|
+
#calculate vector of the spring
|
21
|
+
force = particle.position.dup
|
22
|
+
force = force.subtractVector(@anchor)
|
23
|
+
# calculate magnitude of the force
|
24
|
+
magnitude = force.magnitude
|
25
|
+
magnitude = (@rest_length - magnitude) * @spring_constant
|
26
|
+
magnitude *= @spring_constant
|
27
|
+
|
28
|
+
#calculate final force and apply it
|
29
|
+
force = force.unit
|
30
|
+
|
31
|
+
force.multiplyByScalar(magnitude)
|
32
|
+
particle.addForce(force)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
module Particles
|
3
|
+
module Collisions
|
4
|
+
|
5
|
+
|
6
|
+
|
7
|
+
# Cables link a pair of particles, generating a contact if they stray too far apart.
|
8
|
+
class ParticleCable < ParticleLink
|
9
|
+
|
10
|
+
|
11
|
+
# Holds the maximum length of the cable.
|
12
|
+
attr_accessor :max_length
|
13
|
+
|
14
|
+
# Holds the restitution (bounciness) of the cable.
|
15
|
+
attr_accessor :restitution
|
16
|
+
|
17
|
+
|
18
|
+
def initialize(particle1, particle2, max_length = 1.0, restitution = 1.0)
|
19
|
+
super(particle1, particle2)
|
20
|
+
@max_length = max_length
|
21
|
+
@restitution = restitution
|
22
|
+
end
|
23
|
+
|
24
|
+
# see ParticleLink for description
|
25
|
+
def add_contact(contactArray, limit)
|
26
|
+
length = (@particle1.position - @particle2.position).magnitude
|
27
|
+
|
28
|
+
|
29
|
+
if( length < @max_length)
|
30
|
+
return 0
|
31
|
+
end
|
32
|
+
|
33
|
+
contact = ParticleContact.new(@particle1, @particle2)
|
34
|
+
|
35
|
+
contact.penetration = length - @max_length
|
36
|
+
contact.restitution = @restitution
|
37
|
+
|
38
|
+
contactArray << contact
|
39
|
+
|
40
|
+
return 1
|
41
|
+
end
|
42
|
+
|
43
|
+
def current_length
|
44
|
+
(@particle1.position - @particle2.position).magnitude
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module BulldogPhysics
|
2
|
+
module Particles
|
3
|
+
module Collisions
|
4
|
+
|
5
|
+
class ParticleContact
|
6
|
+
|
7
|
+
attr_accessor :particle1
|
8
|
+
attr_accessor :particle2
|
9
|
+
attr_accessor :restitution
|
10
|
+
attr_accessor :contact_normal
|
11
|
+
attr_accessor :penetration
|
12
|
+
|
13
|
+
def initialize(particle1, particle2 = nil, contact_normal = Vector3.new(0,1,0), penetration = 0)
|
14
|
+
@particle1 = particle1
|
15
|
+
@particle2 = particle2
|
16
|
+
@penetration = penetration
|
17
|
+
@contact_normal = contact_normal
|
18
|
+
unless @particle2.nil?
|
19
|
+
@contact_normal = (@particle1.position - @particle2.position).unit
|
20
|
+
#@penetration = (@particle1.position - @particle2.position).magnitude.abs - (@particle1.radius + @particle2.radius)
|
21
|
+
#puts "PENETRATION #{@penetration}"
|
22
|
+
end
|
23
|
+
@restitution = 0.0
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve(duration)
|
27
|
+
resolve_velocity(duration)
|
28
|
+
resolve_interpenetration(duration)
|
29
|
+
end
|
30
|
+
|
31
|
+
def calculate_separating_velocity
|
32
|
+
relative_velocity = @particle1.velocity
|
33
|
+
unless @particle2.nil?
|
34
|
+
relative_velocity -= @particle2.velocity
|
35
|
+
end
|
36
|
+
return relative_velocity.scalarProduct(@contact_normal)
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def resolve_velocity(duration)
|
43
|
+
|
44
|
+
#Find the velocity in the direction of the contact.
|
45
|
+
separating_velocity = calculate_separating_velocity()
|
46
|
+
|
47
|
+
# Check if it needs to be resolved.
|
48
|
+
if(separating_velocity > 0)
|
49
|
+
# The contact is either separating, or stationary; there’s no impulse required.
|
50
|
+
return
|
51
|
+
end
|
52
|
+
new_sep_velocity = -separating_velocity * @restitution
|
53
|
+
delta_velocity = new_sep_velocity - separating_velocity
|
54
|
+
|
55
|
+
total_inverse_mass = @particle1.inverse_mass
|
56
|
+
|
57
|
+
|
58
|
+
unless( @particle2.nil? )
|
59
|
+
total_inverse_mass += @particle2.inverse_mass
|
60
|
+
end
|
61
|
+
|
62
|
+
if( total_inverse_mass <= 0)
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
impulse = delta_velocity / total_inverse_mass
|
67
|
+
|
68
|
+
impulse_per_i_mass = @contact_normal * impulse
|
69
|
+
|
70
|
+
@particle1.velocity = @particle1.velocity + ( impulse_per_i_mass * @particle1.inverse_mass )
|
71
|
+
|
72
|
+
unless( @particle2.nil? )
|
73
|
+
@particle2.velocity = @particle2.velocity + (impulse_per_i_mass * -@particle2.inverse_mass )
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
def resolve_interpenetration(duration)
|
79
|
+
if(@penetration <= 0)
|
80
|
+
return
|
81
|
+
end
|
82
|
+
|
83
|
+
total_inverse_mass = @particle1.inverse_mass
|
84
|
+
unless( @particle2.nil? )
|
85
|
+
total_inverse_mass += @particle2.inverse_mass
|
86
|
+
end
|
87
|
+
|
88
|
+
if(total_inverse_mass <= 0)
|
89
|
+
return
|
90
|
+
end
|
91
|
+
|
92
|
+
# Calculate the movement amounts.
|
93
|
+
move_per_i_mass = @contact_normal * (@penetration / total_inverse_mass)
|
94
|
+
|
95
|
+
particle_movement_1 = move_per_i_mass * @particle1.inverse_mass
|
96
|
+
particle_movement_2 = Vector3.new
|
97
|
+
|
98
|
+
unless( @particle2.nil? )
|
99
|
+
particle_movement_2 = move_per_i_mass * -@particle2.inverse_mass
|
100
|
+
else
|
101
|
+
particle_movement_2.clear()
|
102
|
+
end
|
103
|
+
|
104
|
+
@particle1.position = @particle1.position + particle_movement_1
|
105
|
+
|
106
|
+
unless( @particle2.nil? )
|
107
|
+
@particle2.position = @particle2.position + particle_movement_2
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
|