processing.rb 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +11 -0
- data/CHANGELOG.md +155 -0
- data/LICENSE +21 -0
- data/README.ja.md +199 -0
- data/README.md +199 -0
- data/bin/setup_processingrb_examples +9 -0
- data/examples/01_simple_sketch.rb +32 -0
- data/examples/02_input_handling.rb +49 -0
- data/examples/03_multi_file.rb +44 -0
- data/examples/04_builtin_library.rb +48 -0
- data/examples/05_external_library.rb +89 -0
- data/examples/data/cat.mov +0 -0
- data/examples/data/dog.mov +0 -0
- data/examples/libraries/handy/library.properties +43 -0
- data/examples/libraries/handy/library/handy.jar +0 -0
- data/examples/modules/moving_box.rb +23 -0
- data/examples/modules/textured_cube.rb +47 -0
- data/examples/screenshots/01_simple_sketch.png +0 -0
- data/examples/screenshots/02_input_handling.png +0 -0
- data/examples/screenshots/03_multi_file.png +0 -0
- data/examples/screenshots/04_builtin_library.png +0 -0
- data/examples/screenshots/05_external_library.png +0 -0
- data/lib/processing.rb +8 -0
- data/lib/processing/sketch_base.rb +54 -0
- data/lib/processing/system.rb +57 -0
- data/lib/sketch_runner/config.rb +64 -0
- data/lib/sketch_runner/launch.rb +11 -0
- data/lib/sketch_runner/runner.rb +108 -0
- data/lib/sketch_runner/setup.rb +85 -0
- data/processing.rb.gemspec +19 -0
- metadata +105 -0
@@ -0,0 +1,9 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative '../lib/sketch_runner/config.rb'
|
5
|
+
|
6
|
+
FileUtils.remove_dir(SketchRunner::EXAMPLES_DEST_DIR, true)
|
7
|
+
FileUtils.cp_r(SketchRunner::EXAMPLES_SRC_DIR, SketchRunner::EXAMPLES_DEST_DIR)
|
8
|
+
|
9
|
+
puts "copied the examples to #{SketchRunner::EXAMPLES_DEST_DIR}"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'processing'
|
2
|
+
|
3
|
+
# An example of the basic sketch structure
|
4
|
+
class Sketch < Processing::SketchBase
|
5
|
+
LINE_RADIUS = 8
|
6
|
+
LINE_SPEED = 3
|
7
|
+
|
8
|
+
def setup
|
9
|
+
size(480, 240)
|
10
|
+
background(96)
|
11
|
+
no_stroke
|
12
|
+
|
13
|
+
@x = @y = LINE_RADIUS
|
14
|
+
@vx = @vy = LINE_SPEED
|
15
|
+
end
|
16
|
+
|
17
|
+
def draw
|
18
|
+
fill(96, 8)
|
19
|
+
rect(0, 0, width, height)
|
20
|
+
|
21
|
+
@x += @vx
|
22
|
+
@y += @vy
|
23
|
+
|
24
|
+
@vx *= -1 if @x <= LINE_RADIUS || @x >= width - LINE_RADIUS
|
25
|
+
@vy *= -1 if @y <= LINE_RADIUS || @y >= height - LINE_RADIUS
|
26
|
+
|
27
|
+
fill(255, 204, 0)
|
28
|
+
ellipse(@x, @y, LINE_RADIUS * 2, LINE_RADIUS * 2)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Processing.start(Sketch.new)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'processing'
|
2
|
+
|
3
|
+
# An example of handling keyboard and mouse input
|
4
|
+
class Sketch < Processing::SketchBase
|
5
|
+
CIRCLE_NUM = 40
|
6
|
+
MIN_RADIUS, MAX_RADIUS = 40, 80
|
7
|
+
MIN_ALPHA, MAX_ALPHA = 64, 255
|
8
|
+
|
9
|
+
def setup
|
10
|
+
size(600, 400)
|
11
|
+
background(32, 96, 160)
|
12
|
+
fill(255)
|
13
|
+
stroke_weight(4)
|
14
|
+
|
15
|
+
@pos = []
|
16
|
+
|
17
|
+
text_size(30)
|
18
|
+
text_align(CENTER)
|
19
|
+
text("Press 'r' to Reload", width / 2, height - 15)
|
20
|
+
end
|
21
|
+
|
22
|
+
def draw
|
23
|
+
# initialize the position array when the mouse moves for the first time
|
24
|
+
if @pos.empty?
|
25
|
+
return if mouse_x == 0 && mouse_y == 0
|
26
|
+
|
27
|
+
(0...CIRCLE_NUM).each do
|
28
|
+
@pos << Processing::PVector.new(mouse_x, mouse_y)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@pos[frame_count % CIRCLE_NUM].set(mouse_x, mouse_y)
|
33
|
+
|
34
|
+
(0...CIRCLE_NUM).each do |i|
|
35
|
+
pos = @pos[(frame_count + i + 1) % CIRCLE_NUM]
|
36
|
+
rad = map(i, 0, CIRCLE_NUM, MAX_RADIUS, MIN_RADIUS)
|
37
|
+
alpha = map(i, 0, CIRCLE_NUM, MIN_ALPHA, MAX_ALPHA)
|
38
|
+
|
39
|
+
stroke(0, 128, 255, alpha)
|
40
|
+
ellipse(pos.x, pos.y, rad, rad)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def key_pressed
|
45
|
+
Processing.reload if key == 'r'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
Processing.start(Sketch.new, pos: [300, 300])
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'processing'
|
2
|
+
|
3
|
+
require_relative 'modules/moving_box'
|
4
|
+
|
5
|
+
# An example of splitting the sketch into multiple files
|
6
|
+
class Sketch < Processing::SketchBase
|
7
|
+
CUBE_NUM = 200
|
8
|
+
|
9
|
+
def setup
|
10
|
+
size(640, 360, OPENGL)
|
11
|
+
background(0)
|
12
|
+
no_stroke
|
13
|
+
|
14
|
+
@angle = 0
|
15
|
+
@boxes = []
|
16
|
+
|
17
|
+
(0...CUBE_NUM).each do |i|
|
18
|
+
@boxes[i] = MovingBox.new(
|
19
|
+
self,
|
20
|
+
random(-280, 280), random(-280, 280), random(-280, 280),
|
21
|
+
random(5, 25), random(5, 25), random(5, 25)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def draw
|
27
|
+
background(192, 97, 70)
|
28
|
+
fill(200)
|
29
|
+
|
30
|
+
point_light(128, 169, 125, -65, 60, -150)
|
31
|
+
point_light(69, 117, 115, 65, -60, 100)
|
32
|
+
ambient_light(80, 58, 71)
|
33
|
+
|
34
|
+
translate(width / 2, height / 2, -200 + mouse_x * 0.65)
|
35
|
+
rotate_y(radians(@angle))
|
36
|
+
rotate_x(radians(@angle))
|
37
|
+
|
38
|
+
@boxes.each(&:draw)
|
39
|
+
|
40
|
+
@angle += 0.2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Processing.start(Sketch.new, topmost: true, pos: [300, 300])
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'processing'
|
2
|
+
require_relative 'modules/textured_cube'
|
3
|
+
|
4
|
+
Processing.load_library 'video'
|
5
|
+
Processing.import_package 'processing.video', 'Video'
|
6
|
+
|
7
|
+
# An example of using Processing-buildin libraries
|
8
|
+
class Sketch < Processing::SketchBase
|
9
|
+
include TexturedCube
|
10
|
+
|
11
|
+
MOVIE1 = Processing.sketch_path('data/cat.mov')
|
12
|
+
MOVIE2 = Processing.sketch_path('data/dog.mov')
|
13
|
+
|
14
|
+
def setup
|
15
|
+
size(800, 400, OPENGL)
|
16
|
+
no_stroke
|
17
|
+
|
18
|
+
@mov1 = Video::Movie.new(self, MOVIE1)
|
19
|
+
@mov1.loop
|
20
|
+
|
21
|
+
@mov2 = Video::Movie.new(self, MOVIE2)
|
22
|
+
@mov2.loop
|
23
|
+
end
|
24
|
+
|
25
|
+
def draw
|
26
|
+
background(80, 100, 180)
|
27
|
+
lights
|
28
|
+
|
29
|
+
@mov1.read if @mov1.available
|
30
|
+
@mov2.read if @mov2.available
|
31
|
+
|
32
|
+
push_matrix
|
33
|
+
|
34
|
+
translate(220, 200, -50)
|
35
|
+
rotate_x(frame_count / 200.0)
|
36
|
+
rotate_y(frame_count / 150.0)
|
37
|
+
textured_cube(220, @mov1, 0.22, 0, 0.78, 1)
|
38
|
+
|
39
|
+
pop_matrix
|
40
|
+
|
41
|
+
translate(580, 200, -50)
|
42
|
+
rotate_x(frame_count / 200.0)
|
43
|
+
rotate_y(frame_count / 150.0)
|
44
|
+
textured_cube(220, @mov2, 0.22, 0, 0.78, 1)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Processing.start(Sketch.new, topmost: true, pos: [300, 300])
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'processing'
|
2
|
+
|
3
|
+
Processing.load_library 'handy'
|
4
|
+
Processing.import_package 'org.gicentre.handy', 'Handy'
|
5
|
+
|
6
|
+
BALL_NUM = 6
|
7
|
+
BALL_COLORS = [[255, 0, 0], [255, 255, 0], [64, 64, 255]]
|
8
|
+
|
9
|
+
# An example of using external libraries for Processing
|
10
|
+
class Sketch < Processing::SketchBase
|
11
|
+
attr_reader :handy
|
12
|
+
|
13
|
+
def setup
|
14
|
+
size(400, 400)
|
15
|
+
|
16
|
+
@handy = Handy::HandyRenderer.new(self)
|
17
|
+
|
18
|
+
@balls = []
|
19
|
+
(0...BALL_NUM).each { |i| @balls << Ball.new(self, i) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def draw
|
23
|
+
background(234, 215, 182)
|
24
|
+
|
25
|
+
fill(0, 255, 0)
|
26
|
+
@handy.instance_eval do
|
27
|
+
rect(20, 20, 360, 20)
|
28
|
+
rect(20, 360, 360, 20)
|
29
|
+
rect(20, 40, 20, 320)
|
30
|
+
rect(360, 40, 20, 320)
|
31
|
+
end
|
32
|
+
|
33
|
+
@balls.each(&:draw)
|
34
|
+
end
|
35
|
+
|
36
|
+
def key_pressed
|
37
|
+
Processing.reload if key == 'r'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Bouncing ball
|
42
|
+
class Ball
|
43
|
+
def initialize(sketch, id)
|
44
|
+
@sketch = sketch
|
45
|
+
|
46
|
+
@x, @y = @sketch.random(100, 300), @sketch.random(100, 300)
|
47
|
+
@vx, @vy = @sketch.random(-6, 6), @sketch.random(-6, 6)
|
48
|
+
|
49
|
+
@size = @sketch.random(60, 100)
|
50
|
+
@radius = @size / 2.0
|
51
|
+
|
52
|
+
@color = BALL_COLORS[id % BALL_COLORS.size]
|
53
|
+
|
54
|
+
@min_x = @min_y = 40 + @radius
|
55
|
+
@max_x = @max_y = 360 - @radius
|
56
|
+
end
|
57
|
+
|
58
|
+
def draw
|
59
|
+
@x += @vx
|
60
|
+
@y += @vy
|
61
|
+
|
62
|
+
@vy += 0.1
|
63
|
+
|
64
|
+
if @x < @min_x
|
65
|
+
@x = @min_x
|
66
|
+
@vx = -@vx
|
67
|
+
end
|
68
|
+
|
69
|
+
if @x > @max_x
|
70
|
+
@x = @max_x
|
71
|
+
@vx = -@vx
|
72
|
+
end
|
73
|
+
|
74
|
+
if @y < @min_y
|
75
|
+
@y = @min_y
|
76
|
+
@vy = -@vy
|
77
|
+
end
|
78
|
+
|
79
|
+
if @y > @max_y
|
80
|
+
@y = @max_y
|
81
|
+
@vy *= -0.99
|
82
|
+
end
|
83
|
+
|
84
|
+
@sketch.fill(*@color)
|
85
|
+
@sketch.handy.ellipse(@x, @y, @size, @size)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
Processing.start(Sketch.new, topmost: true, pos: [300, 300])
|
Binary file
|
Binary file
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# The name of your library as you want it formatted
|
2
|
+
name = handy
|
3
|
+
|
4
|
+
# List of authors. Links can be provided using the syntax [author name](url)
|
5
|
+
authorList = [Jo Wood](http://gicentre.org/)
|
6
|
+
|
7
|
+
# A website for your library
|
8
|
+
url = http://www.gicentre.org/handy
|
9
|
+
|
10
|
+
# The category of your library, must be one of the following:
|
11
|
+
# "Sound" "Import / Export" "Simulation / Math"
|
12
|
+
# "Tools" "Hardware Interface" "Typography / Geometry"
|
13
|
+
# "Animation" "Graphic Interface" "Computer Vision / Video"
|
14
|
+
# "3D" "Compilation" "Data / Protocols"
|
15
|
+
#
|
16
|
+
# If a value other than those listed is used, your library will listed as "Other."
|
17
|
+
category = "Graphic Interface"
|
18
|
+
|
19
|
+
# A short sentence (fragment) to summarize the library's function. This will be
|
20
|
+
# shown from inside the PDE when the library is being installed. Avoid repeating
|
21
|
+
# the name of your library here. Also, avoid saying anything redundant like
|
22
|
+
# mentioning that its a library.
|
23
|
+
sentence = Hand-drawn sketchy rendering.
|
24
|
+
|
25
|
+
# Additional information suitable for the Processing website. The value of
|
26
|
+
# 'sentence' always will be prepended, so you should start by writing the
|
27
|
+
# second sentence here. If your library only works on certain operating systems,
|
28
|
+
# mention it here.
|
29
|
+
paragraph = Allows you to produce graphics with a hand-drawn appearance. Appearance can be customised to produce a variety of styles including pencil, ball-point pen and marker pen appearance. For documentation and examples, see the [handy pages](http://www.gicentre.org/handy/).
|
30
|
+
|
31
|
+
# Links in the 'sentence' and 'paragraph' attributes can be inserted using the
|
32
|
+
# same syntax as for authors. That is, [here is a link to Processing](http://processing.org/)
|
33
|
+
|
34
|
+
# A version number that increments once with each release. This
|
35
|
+
# is used to compare different versions of the same library, and
|
36
|
+
# check if an update is available. You should think of it as a
|
37
|
+
# counter, counting the total number of releases you've had.
|
38
|
+
# This must be parsable as an int
|
39
|
+
version = 1
|
40
|
+
|
41
|
+
# The version as the user will see it. If blank, the version attribute will be used here
|
42
|
+
# This is treated as a String
|
43
|
+
prettyVersion = 1.0
|
Binary file
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Draws a moving box of the speficied size
|
2
|
+
class MovingBox
|
3
|
+
def initialize(sketch, x, y, z, w, h, d)
|
4
|
+
@sketch = sketch
|
5
|
+
@x, @y, @z = x, y, z
|
6
|
+
@w, @h, @d = w, h, d
|
7
|
+
end
|
8
|
+
|
9
|
+
def draw
|
10
|
+
x, y, z = @x, @y, @z
|
11
|
+
w, h, d = @w, @h, @d
|
12
|
+
|
13
|
+
@sketch.instance_eval do
|
14
|
+
push_matrix
|
15
|
+
|
16
|
+
x += sin(frame_count / 10.0 + y) * 10.0
|
17
|
+
translate(x, y, z)
|
18
|
+
box(w, h, d)
|
19
|
+
|
20
|
+
pop_matrix
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Draws the cube with the specified texture
|
2
|
+
module TexturedCube
|
3
|
+
def textured_cube(size, pimage, u1, v1, u2, v2)
|
4
|
+
w = h = d = size / 2.0
|
5
|
+
|
6
|
+
u1 *= pimage.width.to_f
|
7
|
+
v1 *= pimage.height.to_f
|
8
|
+
u2 *= pimage.width.to_f
|
9
|
+
v2 *= pimage.height.to_f
|
10
|
+
|
11
|
+
begin_shape(Processing::SketchBase::QUADS)
|
12
|
+
|
13
|
+
texture(pimage)
|
14
|
+
|
15
|
+
vertex(-w, -h, d, u1, v1)
|
16
|
+
vertex(w, -h, d, u2, v1)
|
17
|
+
vertex(w, h, d, u2, v2)
|
18
|
+
vertex(-w, h, d, u1, v2)
|
19
|
+
|
20
|
+
vertex(w, -h, -d, u1, v1)
|
21
|
+
vertex(-w, -h, -d, u2, v1)
|
22
|
+
vertex(-w, h, -d, u2, v2)
|
23
|
+
vertex(w, h, -d, u1, v2)
|
24
|
+
|
25
|
+
vertex(-w, h, d, u1, v1)
|
26
|
+
vertex(w, h, d, u2, v1)
|
27
|
+
vertex(w, h, -d, u2, v2)
|
28
|
+
vertex(-w, h, -d, u1, v2)
|
29
|
+
|
30
|
+
vertex(-w, -h, -d, u1, v1)
|
31
|
+
vertex(w, -h, -d, u2, v1)
|
32
|
+
vertex(w, -h, d, u2, v2)
|
33
|
+
vertex(-w, -h, d, u1, v2)
|
34
|
+
|
35
|
+
vertex(w, -h, d, u1, v1)
|
36
|
+
vertex(w, -h, -d, u2, v1)
|
37
|
+
vertex(w, h, -d, u2, v2)
|
38
|
+
vertex(w, h, d, u1, v2)
|
39
|
+
|
40
|
+
vertex(-w, -h, -d, u1, v1)
|
41
|
+
vertex(-w, -h, d, u2, v1)
|
42
|
+
vertex(-w, h, d, u2, v2)
|
43
|
+
vertex(-w, h, -d, u1, v2)
|
44
|
+
|
45
|
+
end_shape
|
46
|
+
end
|
47
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/lib/processing.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# Provides the classes and methods for a Processing sketch
|
2
|
+
module Processing
|
3
|
+
include_package 'processing.core'
|
4
|
+
include_package 'processing.opengl'
|
5
|
+
|
6
|
+
# The base class of a Processing sketch
|
7
|
+
class SketchBase < PApplet
|
8
|
+
%w(displayHeight displayWidth frameCount keyCode
|
9
|
+
mouseButton mouseX mouseY pmouseX pmouseY).each do |name|
|
10
|
+
sc_name = name.split(/(?![a-z])(?=[A-Z])/).map(&:downcase).join('_')
|
11
|
+
alias_method sc_name, name
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.method_added(name)
|
15
|
+
name = name.to_s
|
16
|
+
if name.include?('_')
|
17
|
+
lcc_name = name.split('_').map(&:capitalize).join('')
|
18
|
+
lcc_name[0] = lcc_name[0].downcase
|
19
|
+
alias_method lcc_name, name if lcc_name != name
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name, *args)
|
24
|
+
self.class.__send__(name, *args) if PApplet.public_methods.include?(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_field_value(name)
|
28
|
+
java_class.declared_field(name).value(to_java(PApplet))
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
super
|
33
|
+
SketchRunner.sketch_instances << self
|
34
|
+
end
|
35
|
+
|
36
|
+
def frame_rate(fps = nil)
|
37
|
+
return get_field_value('frameRate') unless fps
|
38
|
+
super(fps)
|
39
|
+
end
|
40
|
+
|
41
|
+
def key
|
42
|
+
code = get_field_value('key')
|
43
|
+
code < 256 ? code.chr : code
|
44
|
+
end
|
45
|
+
|
46
|
+
def key_pressed?
|
47
|
+
get_field_value('keyPressed')
|
48
|
+
end
|
49
|
+
|
50
|
+
def mouse_pressed?
|
51
|
+
get_field_value('mousePressed')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|