propane 0.3.0.pre-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.mvn/extensions.xml +8 -0
  4. data/.mvn/wrapper/maven-wrapper.properties +1 -0
  5. data/.travis.yml +9 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +69 -0
  9. data/Rakefile +59 -0
  10. data/VERSION.txt +4 -0
  11. data/bin/propane +8 -0
  12. data/examples/complete/Rakefile +32 -0
  13. data/examples/complete/data/Texture01.jpg +0 -0
  14. data/examples/complete/data/Texture02.jpg +0 -0
  15. data/examples/complete/data/Univers45.vlw +0 -0
  16. data/examples/complete/data/displaceFrag.glsl +8 -0
  17. data/examples/complete/data/displaceVert.glsl +201 -0
  18. data/examples/complete/glsl_heightmap_noise.rb +121 -0
  19. data/examples/complete/kinetic_type.rb +79 -0
  20. data/examples/regular/Rakefile +30 -0
  21. data/examples/regular/arcball_box.rb +36 -0
  22. data/examples/regular/creating_colors.rb +57 -0
  23. data/examples/regular/elegant_ball.rb +159 -0
  24. data/examples/regular/flight_patterns.rb +63 -0
  25. data/examples/regular/grey_circles.rb +28 -0
  26. data/examples/regular/jwishy.rb +100 -0
  27. data/examples/regular/letters.rb +42 -0
  28. data/examples/regular/lib/boundary.rb +38 -0
  29. data/examples/regular/lib/particle.rb +77 -0
  30. data/examples/regular/lib/particle_system.rb +111 -0
  31. data/examples/regular/liquidy.rb +40 -0
  32. data/examples/regular/mouse_button_demo.rb +34 -0
  33. data/examples/regular/polyhedrons.rb +248 -0
  34. data/examples/regular/ribbon_doodle.rb +89 -0
  35. data/examples/regular/vector_math.rb +36 -0
  36. data/examples/regular/words.rb +41 -0
  37. data/lib/PROCESSING_LICENSE.txt +456 -0
  38. data/lib/export.txt +10 -0
  39. data/lib/propane.rb +12 -0
  40. data/lib/propane/app.rb +197 -0
  41. data/lib/propane/helper_methods.rb +177 -0
  42. data/lib/propane/helpers/numeric.rb +9 -0
  43. data/lib/propane/library_loader.rb +117 -0
  44. data/lib/propane/runner.rb +88 -0
  45. data/lib/propane/underscorer.rb +19 -0
  46. data/lib/propane/version.rb +5 -0
  47. data/library/boids/boids.rb +201 -0
  48. data/library/control_panel/control_panel.rb +172 -0
  49. data/pom.rb +113 -0
  50. data/pom.xml +198 -0
  51. data/propane.gemspec +28 -0
  52. data/src/monkstone/ColorUtil.java +67 -0
  53. data/src/monkstone/MathTool.java +195 -0
  54. data/src/monkstone/PropaneLibrary.java +47 -0
  55. data/src/monkstone/core/AbstractLibrary.java +102 -0
  56. data/src/monkstone/fastmath/Deglut.java +115 -0
  57. data/src/monkstone/vecmath/AppRender.java +87 -0
  58. data/src/monkstone/vecmath/JRender.java +56 -0
  59. data/src/monkstone/vecmath/ShapeRender.java +87 -0
  60. data/src/monkstone/vecmath/vec2/Vec2.java +670 -0
  61. data/src/monkstone/vecmath/vec3/Vec3.java +708 -0
  62. data/test/respond_to_test.rb +208 -0
  63. data/vendors/Rakefile +48 -0
  64. metadata +130 -0
@@ -0,0 +1,88 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+ require "#{PROPANE_ROOT}/lib/propane"
4
+ require "#{PROPANE_ROOT}/lib/propane/app"
5
+ require 'optparse'
6
+
7
+ module Propane
8
+ # Utility class to handle the different commands that the 'rp5' command
9
+ # offers. Able to run, watch, live, create, app, and unpack
10
+ class Runner
11
+ attr_reader :options, :name
12
+
13
+ def initialize
14
+ @options = {}
15
+ end
16
+
17
+ # Start running a propane sketch from the passed-in arguments
18
+ def self.execute
19
+ runner = new
20
+ runner.parse_options(ARGV)
21
+ runner.execute!
22
+ end
23
+
24
+ # Dispatch central.
25
+ def execute!
26
+ show_help if options.empty?
27
+ show_version if options[:version]
28
+ run_sketch if options[:run]
29
+ install if options[:install]
30
+ end
31
+
32
+ # Parse the command-line options. Keep it simple.
33
+ def parse_options(args)
34
+ opt_parser = OptionParser.new do |opts|
35
+ # Set a banner, displayed at the top
36
+ # of the help screen.
37
+ opts.banner = 'Usage: propane [options] sketch.rb'
38
+
39
+ # Define the options, and what they do
40
+ options[:version] = false
41
+ opts.on('-v', '--version', 'Propane Version') do
42
+ options[:version] = true
43
+ end
44
+
45
+ options[:install] = false
46
+ opts.on('-i', '--install', 'Installs jruby-complete') do
47
+ options[:install] = true
48
+ end
49
+
50
+ options[:run] = false
51
+ opts.on('-r', '--run', 'Run the sketch using jruby-complete') do
52
+ options[:run] = true
53
+ end
54
+
55
+ # This displays the help screen, all programs are
56
+ # assumed to have this option.
57
+ opts.on('-h', '--help', 'Display this screen') do
58
+ puts opts
59
+ exit
60
+ end
61
+ end
62
+ @name = opt_parser.parse(args)
63
+ end
64
+
65
+ def run_sketch
66
+ root = File.absolute_path(File.dirname(ARGV.shift))
67
+ sketch = File.join(root, name)
68
+ warn_format = 'File %s does not not Exist!'
69
+ return warn(format(warn_format, sketch)) unless File.exist?(sketch)
70
+ command = [
71
+ 'java',
72
+ '-cp',
73
+ "#{PROPANE_ROOT}/lib/ruby/jruby-complete.jar",
74
+ 'org.jruby.Main',
75
+ sketch.to_s
76
+ ].flatten
77
+ exec(*command)
78
+ end
79
+
80
+ def show_version
81
+ puts format('Propane version %s', Propane::VERSION)
82
+ end
83
+
84
+ def install
85
+ system "cd #{PROPANE_ROOT}/vendors && rake"
86
+ end
87
+ end # class Runner
88
+ end # module Propane
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: false
3
+ module Propane
4
+ # This class defines a single method that converts a method name
5
+ # from camel or mixed case to snake case.
6
+ #
7
+ class Underscorer
8
+ # Underscorer.("CamelCase") => "camel_case"
9
+ #
10
+ def self.call(input)
11
+ string = input.to_s
12
+ string.gsub(/::/, '/')
13
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
14
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
15
+ .tr('-', '_')
16
+ .downcase
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module Propane
4
+ VERSION = '0.3.0.pre'.freeze
5
+ end
@@ -0,0 +1,201 @@
1
+ # Boids -- after Tom de Smedt.
2
+ # See his Python version: http://nodebox.net/code/index.php/Boids
3
+ # This is an example of how a pure-Ruby library can work. Original for
4
+ # ruby-processing Jeremy Ashkenas. Reworked, re-factored for JRubyArt 0.9+
5
+ # by Martin Prout, features forwardable, keyword args, Vec3D and Vec2D.
6
+ class Boid
7
+ attr_accessor :boids, :pos, :vel, :is_perching, :perch_time
8
+
9
+ def initialize(boids, pos)
10
+ @boids, @flock = boids, boids
11
+ @pos = pos
12
+ @vel = Vec3D.new
13
+ @is_perching = false
14
+ @perch_time = 0.0
15
+ end
16
+
17
+ def cohesion(d:)
18
+ # Boids gravitate towards the center of the flock,
19
+ # Which is the averaged position of the rest of the boids.
20
+ vect = Vec3D.new
21
+ @boids.each do |boid|
22
+ vect += boid.pos unless boid == self
23
+ end
24
+ count = @boids.length - 1.0
25
+ vect /= count
26
+ (vect - pos) / d
27
+ end
28
+
29
+ def separation(radius:)
30
+ # Boids don't like to cuddle.
31
+ vect = Vec3D.new
32
+ @boids.each do |boid|
33
+ if boid != self
34
+ dv = pos - boid.pos
35
+ vect += dv if dv.mag < radius
36
+ end
37
+ end
38
+ vect
39
+ end
40
+
41
+ def alignment(d:)
42
+ # Boids like to fly at the speed of traffic.
43
+ vect = Vec3D.new
44
+ @boids.each do |boid|
45
+ vect += boid.vel if boid != self
46
+ end
47
+ count = @boids.length - 1.0
48
+ vect /= count
49
+ (vect - vel) / d
50
+ end
51
+
52
+ def limit(max:)
53
+ # Tweet, Tweet! The boid police will bust you for breaking the speed limit.
54
+ most = [vel.x.abs, vel.y.abs, vel.z.abs].max
55
+ return if most < max
56
+ scale = max / most.to_f
57
+ @vel *= scale
58
+ end
59
+
60
+ def angle
61
+ Vec2D.new(vel.x, vel.y).heading
62
+ end
63
+
64
+ def goal(target, d = 50.0)
65
+ # Them boids is hungry.
66
+ (target - pos) / d
67
+ end
68
+ end
69
+
70
+ require 'forwardable'
71
+
72
+ # The Boids class
73
+ class Boids
74
+ include Enumerable
75
+ extend Forwardable
76
+ def_delegators(:@boids, :reject, :<<, :each, :shuffle!, :length, :next)
77
+
78
+ attr_reader :has_goal, :perch, :perch_tm, :perch_y
79
+
80
+ def initialize
81
+ @boids = []
82
+ end
83
+
84
+ def self.flock(n:, x:, y:, w:, h:)
85
+ flock = Boids.new.setup(n, x, y, w, h)
86
+ flock.goal(target: Vec3D.new(w / 2, h / 2, 0))
87
+ end
88
+
89
+ def setup(n, x, y, w, h)
90
+ n.times do
91
+ dx, dy = rand(w), rand(h)
92
+ z = rand(200.0)
93
+ self << Boid.new(self, Vec3D.new(x + dx, y + dy, z))
94
+ end
95
+ @x, @y, @w, @h = x, y, w, h
96
+ @scattered = false
97
+ @scatter = 0.005
98
+ @scatter_time = 50.0
99
+ @scatter_i = 0.0
100
+ @perch = 1.0 # Lower this number to divebomb.
101
+ @perch_y = h
102
+ @perch_tm = -> { 25.0 + rand(50.0) }
103
+ @has_goal = false
104
+ @flee = false
105
+ @goal = Vec3D.new
106
+ self
107
+ end
108
+
109
+ def scatter(chance = 0.005, frames = 50.0)
110
+ @scatter = chance
111
+ @scatter_time = frames
112
+ end
113
+
114
+ def no_scatter
115
+ @scatter = 0.0
116
+ end
117
+
118
+ def perch(ground = nil, chance = 1.0, frames = nil)
119
+ @perch_tm = frames.nil? ? -> { 25.0 + rand(50.0) } : frames
120
+ @perch_y = ground.nil? ? @h : ground
121
+ @perch = chance
122
+ end
123
+
124
+ def no_perch
125
+ @perch = 0.0
126
+ end
127
+
128
+ def goal(target:, flee: false)
129
+ @has_goal = true
130
+ @flee = flee
131
+ @goal = target
132
+ self
133
+ end
134
+
135
+ def no_goal
136
+ @has_goal = false
137
+ end
138
+
139
+ def constrain
140
+ # Put them boids in a cage.
141
+ dx, dy = @w * 0.1, @h * 0.1
142
+ each do |b|
143
+ b.vel.x += rand(dx) if b.pos.x < @x - dx
144
+ b.vel.x += rand(dy) if b.pos.y < @y - dy
145
+ b.vel.x -= rand(dx) if b.pos.x > @x + @w + dx
146
+ b.vel.y -= rand(dy) if b.pos.y > @y + @h + dy
147
+ b.vel.z += 10.0 if b.pos.z < 0.0
148
+ b.vel.z -= 10.0 if b.pos.z > 100.0
149
+ next unless b.pos.y > perch_y && rand < perch
150
+ b.pos.y = perch_y
151
+ b.vel.y = -(b.vel.y.abs) * 0.2
152
+ b.is_perching = true
153
+ b.perch_time = perch_tm.respond_to?(:call) ? perch_tm.call : perch_tm
154
+ end
155
+ end
156
+
157
+ def update(goal: 20.0, limit: 30.0, **args)
158
+ shuffled = args.fetch(:shuffled, true)
159
+ cohesion = args.fetch(:cohesion, 100)
160
+ separation = args.fetch(:separation, 10)
161
+ alignment = args.fetch(:alignment, 5.0)
162
+ # Just flutter, little boids ... just flutter away.
163
+ # Shuffling keeps things flowing smooth.
164
+ shuffle! if shuffled
165
+ m1 = 1.0 # cohesion
166
+ m2 = 1.0 # separation
167
+ m3 = 1.0 # alignment
168
+ m4 = 1.0 # goal
169
+ @scattered = true if !(@scattered) && rand < @scatter
170
+ if @scattered
171
+ m1 = -m1
172
+ m3 *= 0.25
173
+ @scatter_i += 1.0
174
+ end
175
+ if @scatter_i >= @scatter_time
176
+ @scattered = false
177
+ @scatter_i = 0.0
178
+ end
179
+ m4 = 0.0 unless has_goal
180
+ m4 = -m4 if @flee
181
+ each do |b|
182
+ if b.is_perching
183
+ if b.perch_time > 0.0
184
+ b.perch_time -= 1.0
185
+ next
186
+ else
187
+ b.is_perching = false
188
+ end
189
+ end
190
+ v1 = b.cohesion(d: cohesion)
191
+ v2 = b.separation(radius: separation)
192
+ v3 = b.alignment(d: alignment)
193
+ v4 = b.goal(@goal, goal)
194
+ # NB: vector must precede scalar in '*' operation below
195
+ b.vel += (v1 * m1 + v2 * m2 + v3 * m3 + v4 * m4)
196
+ b.limit(max: limit)
197
+ b.pos += b.vel
198
+ end
199
+ constrain
200
+ end
201
+ end
@@ -0,0 +1,172 @@
1
+ # Here's a little library for quickly hooking up controls to sketches.
2
+ # For messing with the parameters and such.
3
+ # These controls will set instance variables on the sketches.
4
+
5
+ # You can make sliders, checkboxes, buttons, and drop-down menus.
6
+ # (optionally) pass the range and default value.
7
+
8
+ module ControlPanel
9
+ # class used to create slider elements for control_panel
10
+ class Slider < javax.swing.JSlider
11
+ def initialize(control_panel, name, range, initial_value, proc = nil)
12
+ min = range.begin * 100
13
+ max = (
14
+ (range.exclude_end? && range.begin.respond_to?(:succ)) ?
15
+ range.max : range.end) * 100
16
+ super(min, max)
17
+ set_minor_tick_spacing((max - min).abs / 10)
18
+ set_paint_ticks true
19
+ # paint_labels = true
20
+ set_preferred_size(java.awt.Dimension.new(190, 30))
21
+ label = control_panel.add_element(self, name)
22
+ add_change_listener do
23
+ update_label(label, name, value)
24
+ $app.instance_variable_set("@#{name}", value) unless value.nil?
25
+ proc.call(value) if proc
26
+ end
27
+ set_value(initial_value ? initial_value * 100 : min)
28
+ fire_state_changed
29
+ end
30
+
31
+ def value
32
+ get_value / 100.0
33
+ end
34
+
35
+ def update_label(label, name, value)
36
+ value = value.to_s
37
+ value << '0' if value.length < 4
38
+ label.set_text "<html><br><b>#{name}: #{value}</b></html>"
39
+ end
40
+ end
41
+
42
+ # class used to combo_box menu elements for control_panel
43
+ class Menu < javax.swing.JComboBox
44
+ def initialize(control_panel, name, elements, initial_value, proc = nil)
45
+ super(elements.to_java(:String))
46
+ set_preferred_size(java.awt.Dimension.new(190, 30))
47
+ control_panel.add_element(self, name)
48
+ add_action_listener do
49
+ $app.instance_variable_set("@#{name}", value) unless value.nil?
50
+ proc.call(value) if proc
51
+ end
52
+ set_selected_index(initial_value ? elements.index(initial_value) : 0)
53
+ end
54
+
55
+ def value
56
+ get_selected_item
57
+ end
58
+ end
59
+
60
+ # Creates check-box elements for control_panel
61
+ class Checkbox < javax.swing.JCheckBox
62
+ def initialize(control_panel, name, proc = nil)
63
+ @control_panel = control_panel
64
+ super(name.to_s)
65
+ set_preferred_size(java.awt.Dimension.new(190, 64))
66
+ set_horizontal_alignment javax.swing.SwingConstants::CENTER
67
+ control_panel.add_element(self, name, false)
68
+ add_action_listener do
69
+ $app.instance_variable_set("@#{name}", value) unless value.nil?
70
+ proc.call(value) if proc
71
+ end
72
+ end
73
+
74
+ def value
75
+ is_selected
76
+ end
77
+ end
78
+
79
+ # Creates button elements for control_panel
80
+ class Button < javax.swing.JButton
81
+ def initialize(control_panel, name, proc = nil)
82
+ super(name.to_s)
83
+ set_preferred_size(java.awt.Dimension.new(170, 64))
84
+ control_panel.add_element(self, name, false, true)
85
+ add_action_listener do
86
+ $app.send(name.to_s)
87
+ proc.call(value) if proc
88
+ end
89
+ end
90
+ end
91
+
92
+ # class used to contain control_panel elements
93
+ class Panel < javax.swing.JFrame
94
+ java_import javax.swing.UIManager
95
+
96
+ attr_accessor :elements, :panel
97
+
98
+ def initialize
99
+ super()
100
+ @elements = []
101
+ @panel = javax.swing.JPanel.new(java.awt.FlowLayout.new(1, 0, 0))
102
+ set_feel
103
+ end
104
+
105
+ def display
106
+ add panel
107
+ set_size 200, 30 + (64 * elements.size)
108
+ set_default_close_operation javax.swing.JFrame::HIDE_ON_CLOSE
109
+ set_resizable false
110
+ set_location($app.width + 10, 0) unless $app.width + 10 > $app.displayWidth
111
+ panel.visible = true
112
+ end
113
+
114
+ def add_element(element, name, has_label = true, _button_ = false)
115
+ if has_label
116
+ label = javax.swing.JLabel.new("<html><br><b>#{name}</b></html>")
117
+ panel.add label
118
+ end
119
+ elements << element
120
+ panel.add element
121
+ has_label ? label : nil
122
+ end
123
+
124
+ def remove
125
+ remove_all
126
+ dispose
127
+ end
128
+
129
+ def slider(name, range = 0..100, initial_value = nil, &block)
130
+ Slider.new(self, name, range, initial_value, block || nil)
131
+ end
132
+
133
+ def menu(name, elements, initial_value = nil, &block)
134
+ Menu.new(self, name, elements, initial_value, block || nil)
135
+ end
136
+
137
+ def checkbox(name, initial_value = nil, &block)
138
+ checkbox = Checkbox.new(self, name, block || nil)
139
+ checkbox.do_click if initial_value == true
140
+ end
141
+
142
+ def button(name, &block)
143
+ Button.new(self, name, block || nil)
144
+ end
145
+
146
+ def look_feel(lf)
147
+ set_feel(lf)
148
+ end
149
+
150
+ private
151
+
152
+ def set_feel(lf = 'metal')
153
+ lafinfo = javax.swing.UIManager.getInstalledLookAndFeels
154
+ laf = lafinfo.select do |info|
155
+ info.getName.eql? lf.capitalize
156
+ end
157
+ javax.swing.UIManager.setLookAndFeel(laf[0].getClassName)
158
+ end
159
+ end
160
+
161
+ # instance methods module
162
+ module InstanceMethods
163
+ def control_panel
164
+ @control_panel ||= ControlPanel::Panel.new
165
+ return @control_panel unless block_given?
166
+ yield(@control_panel)
167
+ @control_panel.display
168
+ end
169
+ end
170
+ end
171
+
172
+ Propane::App.send :include, ControlPanel::InstanceMethods