pbox2d 0.3.1-java → 0.4.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,86 @@
1
+ # The Nature of Code
2
+ # Daniel Shiffman
3
+ # http://natureofcode.com
4
+ require 'forwardable'
5
+
6
+ # A circular particle
7
+ class Particle
8
+ extend Forwardable
9
+ def_delegators(:@app, :box2d, :push_matrix, :pop_matrix, :fill, :rotate,
10
+ :line, :stroke_weight, :translate, :rect_mode, :stroke,
11
+ :ellipse, :height)
12
+ # We need to keep track of a Body and a radius
13
+ attr_reader :body, :r
14
+
15
+ def initialize(x, y, r)
16
+ @app = $app
17
+ @r = r
18
+ # This function puts the particle in the Box2d world
19
+ makeBody(x, y, r)
20
+ body.setUserData(self)
21
+ end
22
+
23
+ # This function removes the particle from the box2d world
24
+ def kill_body
25
+ box2d.destroyBody(body)
26
+ end
27
+
28
+ # Is the particle ready for deletion?
29
+ def done?
30
+ # Let's find the screen position of the particle
31
+ pos = box2d.body_coord(body)
32
+ # Is it off the bottom of the screen?
33
+ if pos.y > height + r * 2
34
+ kill_body
35
+ return true
36
+ end
37
+ false
38
+ end
39
+
40
+ #
41
+ def display
42
+ # We look at each body and get its screen position
43
+ pos = box2d.body_coord(body)
44
+ # Get its angle of rotation
45
+ a = body.getAngle
46
+ push_matrix
47
+ translate(pos.x, pos.y)
48
+ rotate(-a)
49
+ fill(127)
50
+ stroke(0)
51
+ stroke_weight(2)
52
+ ellipse(0, 0, r * 2, r * 2)
53
+ # Let's add a line so we can see the rotation
54
+ line(0, 0, r, 0)
55
+ pop_matrix
56
+ end
57
+
58
+ # Here's our function that adds the particle to the Box2D world
59
+ def makeBody(x, y, r)
60
+ # Define a body
61
+ bd = BodyDef.new
62
+ # Set its position
63
+ bd.position = box2d.processing_to_world(x, y)
64
+ bd.type = BodyType::DYNAMIC
65
+
66
+ @body = box2d.world.createBody(bd)
67
+
68
+ # Make the body's shape a circle
69
+ cs = CircleShape.new
70
+ cs.m_radius = box2d.scale_to_world(r)
71
+
72
+ fd = FixtureDef.new
73
+ fd.shape = cs
74
+
75
+ fd.density = 2.0
76
+ fd.friction = 0.01
77
+ fd.restitution = 0.3 # Restitution is bounciness
78
+
79
+ body.createFixture(fd)
80
+
81
+ # Give it a random initial velocity (and angular velocity)
82
+ # body.setLinearVelocity(Vec2.new(rand(-10.0..10), rand(5.0..10)))
83
+ body.setAngularVelocity(rand(-10.0..10))
84
+ end
85
+ end
86
+
@@ -0,0 +1,44 @@
1
+ # The Nature of Code
2
+ # Daniel Shiffman
3
+ # http://natureofcode.com
4
+
5
+ # Example demonstrating revolute joint
6
+ require 'pbox2d'
7
+ require_relative 'windmill'
8
+ require_relative 'particle'
9
+
10
+ attr_reader :box2d, :windmill, :particles
11
+
12
+ def setup
13
+ size(640,360)
14
+ @box2d = Box2D.new(self)
15
+ box2d.createWorld
16
+ @windmill = Windmill.new(width / 2, 175)
17
+ @particles = []
18
+ end
19
+
20
+ # Click the mouse to turn on or off the motor
21
+ def mouse_pressed
22
+ windmill.toggle_motor
23
+ end
24
+
25
+ def draw
26
+ background(255)
27
+ if rand < 0.1
28
+ sz = rand(4.0..8)
29
+ particles << Particle.new(rand(width / 2 - 100..width / 2 + 100), -20, sz)
30
+ end
31
+ # Look at all particles, in reverse order
32
+ particles.reverse_each do |p|
33
+ p.display
34
+ # Particles that leave the screen, we delete them
35
+ # (note they have to be deleted from both the box2d world and our list
36
+ next unless p.done?
37
+ particles.shift
38
+ end
39
+ # Draw the windmill
40
+ windmill.display
41
+ status = windmill.motor_on? ? "ON" : "OFF"
42
+ fill(0)
43
+ text(format("Click mouse to toggle motor.\nMotor: %s", status), 10, height - 30)
44
+ end
@@ -0,0 +1,53 @@
1
+ # The Nature of Code
2
+ # Daniel Shiffman
3
+ # http://natureofcode.com
4
+ require 'forwardable'
5
+ require_relative 'box'
6
+
7
+ # Class to describe a fixed spinning object
8
+ class Windmill
9
+ extend Forwardable
10
+ def_delegators(:@app, :ellipse, :no_stroke, :box2d, :fill)
11
+ # Our object is two boxes and one joint
12
+ # Consider making the fixed box much smaller and not drawing it
13
+ attr_reader :joint, :box1, :box2
14
+
15
+ def initialize(x, y)
16
+ @app = $app
17
+ # Initialize locations of two boxes
18
+ @box1 = Box.new(x, y - 20, 120, 10, false)
19
+ @box2 = Box.new(x, y, 10, 40, true)
20
+ # Define joint as between two bodies
21
+ rjd = RevoluteJointDef.new
22
+ # NB: using java_send to access the unreachable 'initialize' method
23
+ rjd.java_send :initialize, [Body, Body, Vec2], box1.body, box2.body, box1.body.getWorldCenter
24
+ # Turning on a motor (optional)
25
+ rjd.motorSpeed = Math::PI * 2 # how fast?
26
+ rjd.maxMotorTorque = 1000.0 # how powerful?
27
+ rjd.enableMotor = false # is it on?
28
+ # There are many other properties you can set for a Revolute joint
29
+ # For example, you can limit its angle between a minimum and a maximum
30
+ # See box2d manual for more
31
+ # Create the joint
32
+ @joint = box2d.world.createJoint(rjd)
33
+ end
34
+
35
+ # Turn the motor on or off
36
+ def toggle_motor
37
+ joint.enableMotor(!joint.isMotorEnabled)
38
+ end
39
+
40
+ def motor_on?
41
+ joint.isMotorEnabled
42
+ end
43
+
44
+ def display
45
+ box2.display
46
+ box1.display
47
+ # Draw anchor just for debug
48
+ anchor = box2d.vector_to_processing(box1.body.getWorldCenter)
49
+ fill(0)
50
+ no_stroke
51
+ ellipse(anchor.x, anchor.y, 8, 8)
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require 'forwardable'
2
+
3
+ CENTER ||= Java::ProcessingCore::PConstants::CENTER
4
+ # The boundary class is used to create a floor in this
5
+ # sketch. Note it does not have a change method
6
+ class Boundary
7
+ extend Forwardable
8
+ def_delegators(:@app, :fill, :stroke, :rect, :rect_mode, :box2d)
9
+ attr_reader :x, :y, :w, :h, :b
10
+ def initialize(app, x, y, w, h)
11
+ @app, @x, @y, @w, @h = app, x, y, w, h
12
+ sd = PolygonShape.new
13
+ box2d_w = box2d.scale_to_world(w / 2)
14
+ box2d_h = box2d.scale_to_world(h / 2)
15
+ sd.set_as_box(box2d_w, box2d_h)
16
+ # Create the body
17
+ bd = BodyDef.new
18
+ bd.type = BodyType::STATIC
19
+ bd.position.set(box2d.processing_to_world(x, y))
20
+ @b = box2d.create_body(bd)
21
+ # Attached the shape to the body using a Fixture
22
+ b.create_fixture(sd, 1)
23
+ b.set_user_data(self)
24
+ end
25
+
26
+ # Draw the boundary, if it were at an angle we'd have to do something fancier
27
+ def display
28
+ fill(0)
29
+ stroke(0)
30
+ rect_mode(CENTER)
31
+ rect(x, y, w, h)
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ # A custom listener allows us to get the physics engine to
2
+ # to call our code, on say contact (collisions)
3
+ class CustomListener
4
+ include ContactListener
5
+
6
+ def begin_contact(cp)
7
+ # Get both fixtures
8
+ f1 = cp.getFixtureA
9
+ f2 = cp.getFixtureB
10
+ # Get both bodies
11
+ b1 = f1.getBody
12
+ b2 = f2.getBody
13
+ # Get our objects that reference these bodies
14
+ o1 = b1.getUserData
15
+ o2 = b2.getUserData
16
+ return unless [o1, o2].all? { |obj| obj.respond_to?(:change) }
17
+ o1.change
18
+ o2.change
19
+ end
20
+
21
+ def end_contact(_cp)
22
+ end
23
+
24
+ def pre_solve(_cp, _m)
25
+ end
26
+
27
+ def post_solve(_cp, _ci)
28
+ end
29
+ end
@@ -0,0 +1,77 @@
1
+ # Note the particle class change method is use to change color to red
2
+ # when two particles collide (no change just hitting boundary)
3
+ class Particle
4
+ extend Forwardable
5
+ def_delegators(:@app, :box2d, :begin_shape, :end_shape, :line, :pop_matrix,
6
+ :ellipse, :translate, :rotate, :stroke, :push_matrix,
7
+ :fill, :no_fill, :stroke_weight)
8
+ attr_accessor :body
9
+ attr_reader :radius, :col
10
+
11
+ def initialize(app, x, y, r)
12
+ @app, @x, @y, @radius = app, x, y, r
13
+ # This function puts the particle in the Box2d world
14
+ make_body(x, y, radius)
15
+ @col = -5_263_441 # grey
16
+ body.setUserData(self)
17
+ end
18
+
19
+ # This function removes the particle from the box2d world
20
+ def kill_body
21
+ box2d.destroy_body(body)
22
+ end
23
+
24
+ # Change color when hit
25
+ def change
26
+ @col = -65_536 # red
27
+ end
28
+
29
+ # Is the particle ready for deletion?
30
+ def done
31
+ # Let's find the screen position of the particle
32
+ pos = box2d.body_coord(body)
33
+ # Is it off the bottom of the screen?
34
+ return false unless pos.y > (box2d.height + radius * 2)
35
+ kill_body
36
+ true
37
+ end
38
+
39
+ def display
40
+ # We look at each body and get its screen position
41
+ pos = box2d.body_coord(body)
42
+ # Get its angle of rotation
43
+ a = body.get_angle
44
+ push_matrix
45
+ translate(pos.x, pos.y)
46
+ rotate(a)
47
+ fill(col)
48
+ stroke(0)
49
+ stroke_weight(1)
50
+ ellipse(0, 0, radius * 2, radius * 2)
51
+ # Let's add a line so we can see the rotation
52
+ line(0, 0, radius, 0)
53
+ pop_matrix
54
+ end
55
+
56
+ # Here's our function that adds the particle to the Box2D world
57
+ def make_body(x, y, r)
58
+ # Define a body
59
+ bd = BodyDef.new
60
+ # Set its position
61
+ bd.position = box2d.processing_to_world(x, y)
62
+ bd.type = BodyType::DYNAMIC
63
+ @body = box2d.create_body(bd)
64
+ # Make the body's shape a circle
65
+ cs = CircleShape.new
66
+ cs.m_radius = box2d.scale_to_world(r)
67
+ fd = FixtureDef.new
68
+ fd.shape = cs
69
+ # Parameters that affect physics
70
+ fd.density = 1
71
+ fd.friction = 0.01
72
+ fd.restitution = 0.3
73
+ # Attach fixture to body
74
+ body.create_fixture(fd)
75
+ body.set_angular_velocity(rand(-10.0..10))
76
+ end
77
+ end
@@ -0,0 +1,25 @@
1
+ require 'pbox2d'
2
+ require 'forwardable'
3
+ require_relative 'lib/custom_listener'
4
+ require_relative 'lib/particle'
5
+ require_relative 'lib/boundary'
6
+
7
+ attr_reader :box2d, :particles, :wall
8
+
9
+ def setup
10
+ size 400, 400
11
+ @box2d = Box2D.new(self)
12
+ box2d.create_world
13
+ box2d.add_listener(CustomListener.new)
14
+ @particles = []
15
+ @wall = Boundary.new(self, width / 2, height - 5, width, 10)
16
+ end
17
+
18
+ def draw
19
+ col = color('#ffffff')
20
+ background(col)
21
+ particles << Particle.new(self, rand(width), 20, rand(4..8)) if rand < 0.1
22
+ particles.each(&:display)
23
+ particles.reject!(&:done)
24
+ wall.display
25
+ end
data/lib/box2d.jar CHANGED
Binary file
data/lib/pbox2d.rb CHANGED
@@ -4,27 +4,23 @@ Dir[File.join(working_directory, '*.jar')].each do |jar|
4
4
  require jar
5
5
  end
6
6
 
7
- # This module allows package access to the wrapped java packages
8
- module PB
9
- include_package 'org.jbox2d.collision.shapes'
10
- include_package 'org.jbox2d.common'
11
- include_package 'org.jbox2d.dynamics'
12
- include_package 'org.jbox2d.dynamics.joints'
13
- include_package 'processing.box2d'
7
+ ContactListener = Java::OrgJbox2dCallbacks::ContactListener
8
+
9
+ def import_class_list(list, string)
10
+ list.each { |d| java_import format(string, d) }
14
11
  end
15
12
 
16
- ContactListener = Java::OrgJbox2dCallbacks::ContactListener
17
- Transform = PB::Transform
18
- Vec2 = PB::Vec2
19
- Body = PB::Body
20
- BodyDef = PB::BodyDef
21
- BodyType = PB::BodyType
22
- World = PB::World
23
- Joint = PB::Joint
24
- JointDef = PB::JointDef
25
- FixtureDef = PB::FixtureDef
26
- PolygonShape = PB::PolygonShape
27
- CircleShape = PB::CircleShape
28
- ChainShape = PB::ChainShape
13
+ common = %w( Vec2 Transform )
14
+ common_format = 'org.jbox2d.common.%s'
15
+ import_class_list(common, common_format)
16
+ shape = %w( PolygonShape CircleShape ChainShape Shape )
17
+ shape_format = 'org.jbox2d.collision.shapes.%s'
18
+ import_class_list(shape, shape_format)
19
+ world = %w( Body BodyDef BodyType World FixtureDef )
20
+ world_format = 'org.jbox2d.dynamics.%s'
21
+ import_class_list(world, world_format)
22
+ joint = %w( Joint JointDef DistanceJointDef RevoluteJoint RevoluteJointDef )
23
+ joint_format = 'org.jbox2d.dynamics.joints.%s'
24
+ import_class_list(joint, joint_format)
29
25
 
30
26
  require_relative 'pbox2d/box2d.rb'
data/lib/pbox2d/box2d.rb CHANGED
@@ -13,15 +13,17 @@ class Box2D < Java::ProcessingBox2d::Box2DProcessing
13
13
  )
14
14
  end
15
15
 
16
+ def step_options(args = {})
17
+ default_step.merge(args)
18
+ set_step(args[:time_step], args[:velocity_iter], args[:position_iter])
19
+ end
20
+
16
21
  def defaults
17
- {scale: 10.0, gravity: [0, -10], warm: true, continuous: true}
22
+ { scale: 10.0, gravity: [0, -10], warm: true, continuous: true }
18
23
  end
19
24
 
20
- def step_options(args = {})
21
- time_step = args.fetch(:time_step, 1.0 / 60)
22
- velocity = args.fetch(:velocity_iter, 8)
23
- position = args.fetch(:position_iter, 10)
24
- set_step(time_step, velocity, position)
25
+ def default_step
26
+ { time_step: 1.0 / 60, velocity_iter: 8, position_iter: 10 }
25
27
  end
26
28
 
27
29
  def gravity(args)
@@ -1,4 +1,4 @@
1
1
  # Module here just to keep namespace tidy
2
2
  module Pbox2D
3
- VERSION = '0.3.1'
3
+ VERSION = '0.4.0'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pbox2d
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: java
6
6
  authors:
7
7
  - Martin Prout
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-09 00:00:00.000000000 Z
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -74,6 +74,28 @@ files:
74
74
  - lib/pbox2d.rb
75
75
  - lib/pbox2d/box2d.rb
76
76
  - lib/pbox2d/version.rb
77
+ - examples/bumpy_surface_noise.rb
78
+ - examples/distance_joint/boundary.rb
79
+ - examples/distance_joint/distance_joint.rb
80
+ - examples/distance_joint/pair.rb
81
+ - examples/distance_joint/particle.rb
82
+ - examples/lib/boundary.rb
83
+ - examples/lib/box.rb
84
+ - examples/lib/custom_shape.rb
85
+ - examples/lib/particle_system.rb
86
+ - examples/lib/surface.rb
87
+ - examples/liquid_fun_test.rb
88
+ - examples/liquidy.rb
89
+ - examples/polygons.rb
90
+ - examples/quick_test.rb
91
+ - examples/revolute_joint/box.rb
92
+ - examples/revolute_joint/particle.rb
93
+ - examples/revolute_joint/revolute_joint.rb
94
+ - examples/revolute_joint/windmill.rb
95
+ - examples/test_contact/lib/boundary.rb
96
+ - examples/test_contact/lib/custom_listener.rb
97
+ - examples/test_contact/lib/particle.rb
98
+ - examples/test_contact/test_contact.rb
77
99
  - lib/box2d.jar
78
100
  - lib/jbox2d-library-2.2.1-ds.jar
79
101
  homepage: https://github.com/ruby-processing/jbox2d