propane 0.3.0.pre-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.
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