rubysketch 0.3.20 → 0.3.22
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.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +2 -2
- data/ChangeLog.md +24 -0
- data/Gemfile +1 -2
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/examples/glsl.rb +5 -8
- data/lib/rubysketch/glsl.rb +29 -16
- data/lib/rubysketch/processing.rb +1085 -679
- data/lib/rubysketch/window.rb +91 -64
- data/lib/rubysketch-glsl.rb +12 -0
- data/rubysketch.gemspec +3 -1
- data/test/processing/helper.rb +11 -0
- data/test/processing/test_graphics.rb +21 -0
- data/test/processing/test_shader.rb +47 -0
- data/test/processing/test_utility.rb +20 -13
- data/test/processing/test_vector.rb +1 -1
- metadata +26 -5
@@ -555,7 +555,7 @@ module RubySketch
|
|
555
555
|
end
|
556
556
|
|
557
557
|
# @private
|
558
|
-
|
558
|
+
def getInternal__()
|
559
559
|
@point
|
560
560
|
end
|
561
561
|
|
@@ -592,6 +592,20 @@ module RubySketch
|
|
592
592
|
@image.height
|
593
593
|
end
|
594
594
|
|
595
|
+
# Applies an image filter.
|
596
|
+
#
|
597
|
+
# overload filter(shader)
|
598
|
+
# overload filter(type)
|
599
|
+
# overload filter(type, param)
|
600
|
+
#
|
601
|
+
# @param shader [Shader] a fragment shader to apply
|
602
|
+
# @param type [THRESHOLD, GRAY, INVERT, BLUR] filter type
|
603
|
+
# @param param [Numeric] a parameter for each filter
|
604
|
+
#
|
605
|
+
def filter(*args)
|
606
|
+
@filter = Shader.createFilter__(*args)
|
607
|
+
end
|
608
|
+
|
595
609
|
# Resizes image.
|
596
610
|
#
|
597
611
|
# @param width [Numeric] width for resized image
|
@@ -624,10 +638,33 @@ module RubySketch
|
|
624
638
|
# @return [nil] nil
|
625
639
|
#
|
626
640
|
def copy(img = nil, sx, sy, sw, sh, dx, dy, dw, dh)
|
641
|
+
blend img, sx, sy, sw, sh, dx, dy, dw, dh, :normal
|
642
|
+
end
|
643
|
+
|
644
|
+
# Blends image.
|
645
|
+
#
|
646
|
+
# @overload blend(sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
647
|
+
# @overload blend(img, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
648
|
+
#
|
649
|
+
# @param img [Image] image for blend source
|
650
|
+
# @param sx [Numeric] x position of source region
|
651
|
+
# @param sy [Numeric] y position of source region
|
652
|
+
# @param sw [Numeric] width of source region
|
653
|
+
# @param sh [Numeric] height of source region
|
654
|
+
# @param dx [Numeric] x position of destination region
|
655
|
+
# @param dy [Numeric] y position of destination region
|
656
|
+
# @param dw [Numeric] width of destination region
|
657
|
+
# @param dh [Numeric] height of destination region
|
658
|
+
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE] blend mode
|
659
|
+
#
|
660
|
+
# @return [nil] nil
|
661
|
+
#
|
662
|
+
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
627
663
|
img ||= self
|
628
664
|
@image.paint do |painter|
|
629
|
-
|
665
|
+
img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
630
666
|
end
|
667
|
+
nil
|
631
668
|
end
|
632
669
|
|
633
670
|
# Saves image to file.
|
@@ -643,6 +680,14 @@ module RubySketch
|
|
643
680
|
@image
|
644
681
|
end
|
645
682
|
|
683
|
+
# @private
|
684
|
+
def drawImage__(painter, *args, **states)
|
685
|
+
shader = painter.shader || @filter&.getInternal__
|
686
|
+
painter.push shader: shader, **states do |_|
|
687
|
+
painter.image getInternal__, *args
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
646
691
|
end# Image
|
647
692
|
|
648
693
|
|
@@ -728,6 +773,159 @@ module RubySketch
|
|
728
773
|
end# Touch
|
729
774
|
|
730
775
|
|
776
|
+
# Shader object.
|
777
|
+
#
|
778
|
+
class Shader
|
779
|
+
|
780
|
+
# Initialize shader object.
|
781
|
+
#
|
782
|
+
# @param vertSrc [String] vertex shader source
|
783
|
+
# @param fragSrc [String] fragment shader source
|
784
|
+
#
|
785
|
+
def initialize(vertSrc, fragSrc)
|
786
|
+
@shader = Rays::Shader.new fragSrc, vertSrc, ENV__
|
787
|
+
end
|
788
|
+
|
789
|
+
# Sets uniform variables.
|
790
|
+
#
|
791
|
+
# @overload set(name, a)
|
792
|
+
# @overload set(name, a, b)
|
793
|
+
# @overload set(name, a, b, c)
|
794
|
+
# @overload set(name, a, b, c, d)
|
795
|
+
# @overload set(name, nums)
|
796
|
+
# @overload set(name, vec)
|
797
|
+
# @overload set(name, vec, ncoords)
|
798
|
+
# @overload set(name, tex)
|
799
|
+
#
|
800
|
+
# @param name [String] uniform variable name
|
801
|
+
# @param a [Numeric] int or float value
|
802
|
+
# @param b [Numeric] int or float value
|
803
|
+
# @param c [Numeric] int or float value
|
804
|
+
# @param d [Numeric] int or float value
|
805
|
+
# @param nums [Array] int or float array
|
806
|
+
# @param vec [Vector] vector
|
807
|
+
# @param ncoords [Integer] number of coordinates, max 4
|
808
|
+
# @param tex [Image] texture image
|
809
|
+
#
|
810
|
+
def setUniform(name, *args)
|
811
|
+
arg = args.first
|
812
|
+
case
|
813
|
+
when Array === arg
|
814
|
+
@shader.uniform name, *arg
|
815
|
+
when Numeric === arg
|
816
|
+
@shader.uniform name, *args
|
817
|
+
when Vector === arg
|
818
|
+
vec, ncoords = args
|
819
|
+
@shader.uniform name, vec.getInternal__.to_a(ncoords || 3)
|
820
|
+
when arg.respond_to?(:getInternal__)
|
821
|
+
@shader.uniform name, arg.getInternal__
|
822
|
+
else
|
823
|
+
raise ArgumentError
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
alias set setUniform
|
828
|
+
|
829
|
+
# @private
|
830
|
+
def getInternal__()
|
831
|
+
@shader
|
832
|
+
end
|
833
|
+
|
834
|
+
# @private
|
835
|
+
ENV__ = {
|
836
|
+
attribute_position: [:vertex, :position],
|
837
|
+
attribute_texcoord: :texCoord,
|
838
|
+
attribute_color: :color,
|
839
|
+
varying_position: :vertPosition,
|
840
|
+
varying_texcoord: :vertTexCoord,
|
841
|
+
varying_color: :vertColor,
|
842
|
+
uniform_position_matrix: [:transform, :transformMatrix],
|
843
|
+
uniform_texcoord_matrix: :texMatrix,
|
844
|
+
uniform_texcoord_min: :texMin,
|
845
|
+
uniform_texcoord_max: :texMax,
|
846
|
+
uniform_texcoord_offset: :texOffset,
|
847
|
+
uniform_texture: [:texMap, :texture]
|
848
|
+
}.freeze
|
849
|
+
|
850
|
+
# @private
|
851
|
+
def self.createFilter__(*args)
|
852
|
+
case arg = args.shift
|
853
|
+
when Shader
|
854
|
+
arg
|
855
|
+
when :threshold
|
856
|
+
self.new(nil, <<~END).tap {|sh| sh.set :threshold, (args.shift || 0.5)}
|
857
|
+
uniform float threshold;
|
858
|
+
uniform sampler2D texMap;
|
859
|
+
varying vec4 vertTexCoord;
|
860
|
+
varying vec4 vertColor;
|
861
|
+
void main() {
|
862
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy) * vertColor;
|
863
|
+
float gray = col.r * 0.3 + col.g * 0.59 + col.b * 0.11;
|
864
|
+
gl_FragColor = vec4(vec3(gray > threshold ? 1.0 : 0.0), 1.0);
|
865
|
+
}
|
866
|
+
END
|
867
|
+
when :gray
|
868
|
+
self.new nil, <<~END
|
869
|
+
uniform sampler2D texMap;
|
870
|
+
varying vec4 vertTexCoord;
|
871
|
+
varying vec4 vertColor;
|
872
|
+
void main() {
|
873
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy);
|
874
|
+
float gray = col.r * 0.3 + col.g * 0.59 + col.b * 0.11;
|
875
|
+
gl_FragColor = vec4(vec3(gray), 1.0) * vertColor;
|
876
|
+
}
|
877
|
+
END
|
878
|
+
when :invert
|
879
|
+
self.new nil, <<~END
|
880
|
+
uniform sampler2D texMap;
|
881
|
+
varying vec4 vertTexCoord;
|
882
|
+
varying vec4 vertColor;
|
883
|
+
void main() {
|
884
|
+
vec4 col = texture2D(texMap, vertTexCoord.xy);
|
885
|
+
gl_FragColor = vec4(vec3(1.0 - col.rgb), 1.0) * vertColor;
|
886
|
+
}
|
887
|
+
END
|
888
|
+
when :blur
|
889
|
+
self.new(nil, <<~END).tap {|sh| sh.set :radius, (args.shift || 1).to_f}
|
890
|
+
#define PI 3.1415926538
|
891
|
+
uniform float radius;
|
892
|
+
uniform sampler2D texMap;
|
893
|
+
uniform vec3 texMin;
|
894
|
+
uniform vec3 texMax;
|
895
|
+
uniform vec3 texOffset;
|
896
|
+
varying vec4 vertTexCoord;
|
897
|
+
varying vec4 vertColor;
|
898
|
+
float gaussian(vec2 pos, float sigma) {
|
899
|
+
float s2 = sigma * sigma;
|
900
|
+
return 1.0 / (2.0 * PI * s2) * exp(-(dot(pos, pos) / (2.0 * s2)));
|
901
|
+
}
|
902
|
+
void main() {
|
903
|
+
float sigma = radius * 0.5;
|
904
|
+
vec3 color = vec3(0.0);
|
905
|
+
float total_weight = 0.0;
|
906
|
+
for (float y = -radius; y < radius; y += 1.0)
|
907
|
+
for (float x = -radius; x < radius; x += 1.0) {
|
908
|
+
vec2 offset = vec2(x, y);
|
909
|
+
float weight = gaussian(offset, sigma);
|
910
|
+
vec2 texcoord = vertTexCoord.xy + offset * texOffset.xy;
|
911
|
+
if (
|
912
|
+
texcoord.x < texMin.x || texMax.x < texcoord.x ||
|
913
|
+
texcoord.y < texMin.y || texMax.y < texcoord.y
|
914
|
+
) continue;
|
915
|
+
color += texture2D(texMap, texcoord).rgb * weight;
|
916
|
+
total_weight += weight;
|
917
|
+
}
|
918
|
+
gl_FragColor = vec4(color / total_weight, 1.0) * vertColor;
|
919
|
+
}
|
920
|
+
END
|
921
|
+
else
|
922
|
+
nil
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
end# Shader
|
927
|
+
|
928
|
+
|
731
929
|
# Camera object.
|
732
930
|
#
|
733
931
|
class Capture
|
@@ -813,14 +1011,31 @@ module RubySketch
|
|
813
1011
|
@camera.image&.height || 0
|
814
1012
|
end
|
815
1013
|
|
1014
|
+
# Applies an image filter.
|
1015
|
+
#
|
1016
|
+
# overload filter(shader)
|
1017
|
+
# overload filter(type)
|
1018
|
+
# overload filter(type, param)
|
1019
|
+
#
|
1020
|
+
# @param shader [Shader] a fragment shader to apply
|
1021
|
+
# @param type [THRESHOLD, GRAY, INVERT, BLUR] filter type
|
1022
|
+
# @param param [Numeric] a parameter for each filter
|
1023
|
+
#
|
1024
|
+
def filter(*args)
|
1025
|
+
@filter = Shader.createFilter__(*args)
|
1026
|
+
end
|
1027
|
+
|
816
1028
|
# @private
|
817
1029
|
def getInternal__()
|
818
|
-
@camera.image ||
|
1030
|
+
@camera.image || (@dummyImage ||= Rays::Image.new 1, 1)
|
819
1031
|
end
|
820
1032
|
|
821
1033
|
# @private
|
822
|
-
|
823
|
-
|
1034
|
+
def drawImage__(painter, *args, **states)
|
1035
|
+
shader = painter.shader || @filter&.getInternal__
|
1036
|
+
painter.push shader: shader, **states do |_|
|
1037
|
+
painter.image getInternal__, *args
|
1038
|
+
end
|
824
1039
|
end
|
825
1040
|
|
826
1041
|
end# Capture
|
@@ -850,13 +1065,17 @@ module RubySketch
|
|
850
1065
|
#
|
851
1066
|
TAU = PI * 2
|
852
1067
|
|
853
|
-
#
|
1068
|
+
# RGBA format for createImage().
|
1069
|
+
#
|
1070
|
+
RGBA = :rgba
|
1071
|
+
|
1072
|
+
# RGB format for createImage, or RGB mode for colorMode().
|
854
1073
|
#
|
855
|
-
RGB
|
1074
|
+
RGB = :rgb
|
856
1075
|
|
857
1076
|
# HSB mode for colorMode().
|
858
1077
|
#
|
859
|
-
HSB
|
1078
|
+
HSB = :hsb
|
860
1079
|
|
861
1080
|
# Radian mode for angleMode().
|
862
1081
|
#
|
@@ -949,6 +1168,18 @@ module RubySketch
|
|
949
1168
|
# Mode for textAlign().
|
950
1169
|
BASELINE = :baseline
|
951
1170
|
|
1171
|
+
# Filter type for filter()
|
1172
|
+
THRESHOLD = :threshold
|
1173
|
+
|
1174
|
+
# Filter type for filter()
|
1175
|
+
GRAY = :gray
|
1176
|
+
|
1177
|
+
# Filter type for filter()
|
1178
|
+
INVERT = :invert
|
1179
|
+
|
1180
|
+
# Filter type for filter()
|
1181
|
+
BLUR = :blur
|
1182
|
+
|
952
1183
|
# Key codes.
|
953
1184
|
ENTER = :enter
|
954
1185
|
SPACE = :space
|
@@ -1009,6 +1240,8 @@ module RubySketch
|
|
1009
1240
|
@imageMode__ = nil
|
1010
1241
|
@textAlignH__ = nil
|
1011
1242
|
@textAlignV__ = nil
|
1243
|
+
@tint__ = nil
|
1244
|
+
@filter__ = nil
|
1012
1245
|
@matrixStack__ = []
|
1013
1246
|
@styleStack__ = []
|
1014
1247
|
@fontCache__ = {}
|
@@ -1021,11 +1254,14 @@ module RubySketch
|
|
1021
1254
|
ellipseMode CENTER
|
1022
1255
|
imageMode CORNER
|
1023
1256
|
blendMode BLEND
|
1257
|
+
strokeCap ROUND
|
1258
|
+
strokeJoin MITER
|
1024
1259
|
textAlign LEFT
|
1025
1260
|
|
1026
1261
|
fill 255
|
1027
1262
|
stroke 0
|
1028
1263
|
strokeWeight 1
|
1264
|
+
noTint
|
1029
1265
|
end
|
1030
1266
|
|
1031
1267
|
# @private
|
@@ -1035,6 +1271,7 @@ module RubySketch
|
|
1035
1271
|
|
1036
1272
|
# @private
|
1037
1273
|
def beginDraw__()
|
1274
|
+
raise "call beginDraw() before drawing" if @drawing__
|
1038
1275
|
@matrixStack__.clear
|
1039
1276
|
@styleStack__.clear
|
1040
1277
|
@drawing__ = true
|
@@ -1042,6 +1279,7 @@ module RubySketch
|
|
1042
1279
|
|
1043
1280
|
# @private
|
1044
1281
|
def endDraw__()
|
1282
|
+
raise unless @drawing__
|
1045
1283
|
@drawing__ = false
|
1046
1284
|
end
|
1047
1285
|
|
@@ -1186,6 +1424,17 @@ module RubySketch
|
|
1186
1424
|
end
|
1187
1425
|
end
|
1188
1426
|
|
1427
|
+
# Sets blend mode. Default is BLEND.
|
1428
|
+
#
|
1429
|
+
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE]
|
1430
|
+
#
|
1431
|
+
# @return [nil] nil
|
1432
|
+
#
|
1433
|
+
def blendMode(mode)
|
1434
|
+
@painter__.blend_mode = mode
|
1435
|
+
nil
|
1436
|
+
end
|
1437
|
+
|
1189
1438
|
# Sets fill color.
|
1190
1439
|
#
|
1191
1440
|
# @overload fill(rgb)
|
@@ -1283,6 +1532,37 @@ module RubySketch
|
|
1283
1532
|
nil
|
1284
1533
|
end
|
1285
1534
|
|
1535
|
+
# Sets fill color for drawing images.
|
1536
|
+
#
|
1537
|
+
# @overload tint(rgb)
|
1538
|
+
# @overload tint(rgb, alpha)
|
1539
|
+
# @overload tint(gray)
|
1540
|
+
# @overload tint(gray, alpha)
|
1541
|
+
# @overload tint(r, g, b)
|
1542
|
+
# @overload tint(r, g, b, alpha)
|
1543
|
+
#
|
1544
|
+
# @param rgb [String] color code like '#00AAFF'
|
1545
|
+
# @param gray [Integer] gray value (0..255)
|
1546
|
+
# @param r [Integer] red value (0..255)
|
1547
|
+
# @param g [Integer] green value (0..255)
|
1548
|
+
# @param b [Integer] blue value (0..255)
|
1549
|
+
# @param alpha [Integer] alpha value (0..255)
|
1550
|
+
#
|
1551
|
+
# @return [nil] nil
|
1552
|
+
#
|
1553
|
+
def tint(*args)
|
1554
|
+
@tint__ = args
|
1555
|
+
nil
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
# Resets tint color.
|
1559
|
+
#
|
1560
|
+
# @return [nil] nil
|
1561
|
+
#
|
1562
|
+
def noTint()
|
1563
|
+
@tint__ = nil
|
1564
|
+
end
|
1565
|
+
|
1286
1566
|
# Limits the drawable rectangle.
|
1287
1567
|
#
|
1288
1568
|
# The parameters a, b, c, and d are determined by rectMode().
|
@@ -1309,17 +1589,6 @@ module RubySketch
|
|
1309
1589
|
nil
|
1310
1590
|
end
|
1311
1591
|
|
1312
|
-
# Sets blend mode. Default is BLEND.
|
1313
|
-
#
|
1314
|
-
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE]
|
1315
|
-
#
|
1316
|
-
# @return [nil] nil
|
1317
|
-
#
|
1318
|
-
def blendMode(mode)
|
1319
|
-
@painter__.blend_mode = mode
|
1320
|
-
nil
|
1321
|
-
end
|
1322
|
-
|
1323
1592
|
# Sets font.
|
1324
1593
|
#
|
1325
1594
|
# @overload textFont(font)
|
@@ -1378,6 +1647,40 @@ module RubySketch
|
|
1378
1647
|
@painter__.font = font
|
1379
1648
|
end
|
1380
1649
|
|
1650
|
+
# Sets shader.
|
1651
|
+
#
|
1652
|
+
# @param shader [Shader] a shader to apply
|
1653
|
+
#
|
1654
|
+
# @return [nil] nil
|
1655
|
+
#
|
1656
|
+
def shader(shader)
|
1657
|
+
@painter__.shader shader&.getInternal__
|
1658
|
+
nil
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
# Resets shader.
|
1662
|
+
#
|
1663
|
+
# @return [nil] nil
|
1664
|
+
#
|
1665
|
+
def resetShader()
|
1666
|
+
@painter__.no_shader
|
1667
|
+
nil
|
1668
|
+
end
|
1669
|
+
|
1670
|
+
# Applies an image filter to screen.
|
1671
|
+
#
|
1672
|
+
# overload filter(shader)
|
1673
|
+
# overload filter(type)
|
1674
|
+
# overload filter(type, param)
|
1675
|
+
#
|
1676
|
+
# @param shader [Shader] a shader to apply
|
1677
|
+
# @param type [THRESHOLD, GRAY, INVERT, BLUR] filter type
|
1678
|
+
# @param param [Numeric] a parameter for each filter
|
1679
|
+
#
|
1680
|
+
def filter(*args)
|
1681
|
+
@filter__ = Shader.createFilter__(*args)
|
1682
|
+
end
|
1683
|
+
|
1381
1684
|
# Clears screen.
|
1382
1685
|
#
|
1383
1686
|
# @overload background(str)
|
@@ -1402,7 +1705,7 @@ module RubySketch
|
|
1402
1705
|
if rgba[3] == 1
|
1403
1706
|
@painter__.background(*rgba)
|
1404
1707
|
else
|
1405
|
-
@painter__.push fill: rgba, stroke:
|
1708
|
+
@painter__.push fill: rgba, stroke: :none do |_|
|
1406
1709
|
@painter__.rect 0, 0, width, height
|
1407
1710
|
end
|
1408
1711
|
end
|
@@ -1418,9 +1721,7 @@ module RubySketch
|
|
1418
1721
|
#
|
1419
1722
|
def point(x, y)
|
1420
1723
|
assertDrawing__
|
1421
|
-
|
1422
|
-
w = 1 if w == 0
|
1423
|
-
@painter__.ellipse x - (w / 2.0), y - (w / 2.0), w, w
|
1724
|
+
@painter__.line x, y, x, y
|
1424
1725
|
nil
|
1425
1726
|
end
|
1426
1727
|
|
@@ -1498,9 +1799,7 @@ module RubySketch
|
|
1498
1799
|
# @return [nil] nil
|
1499
1800
|
#
|
1500
1801
|
def circle(x, y, extent)
|
1501
|
-
|
1502
|
-
@painter__.ellipse x, y, extent, extent
|
1503
|
-
nil
|
1802
|
+
ellipse x, y, extent, extent
|
1504
1803
|
end
|
1505
1804
|
|
1506
1805
|
# Draws an arc.
|
@@ -1667,9 +1966,9 @@ module RubySketch
|
|
1667
1966
|
#
|
1668
1967
|
def image(img, a, b, c = nil, d = nil)
|
1669
1968
|
assertDrawing__
|
1670
|
-
|
1671
|
-
|
1672
|
-
@painter__
|
1969
|
+
x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
|
1970
|
+
tint = @tint__ ? toRGBA__(*@tint__) : 1
|
1971
|
+
img.drawImage__ @painter__, x, y, w, h, fill: tint, stroke: :none
|
1673
1972
|
nil
|
1674
1973
|
end
|
1675
1974
|
|
@@ -1691,9 +1990,39 @@ module RubySketch
|
|
1691
1990
|
# @return [nil] nil
|
1692
1991
|
#
|
1693
1992
|
def copy(img = nil, sx, sy, sw, sh, dx, dy, dw, dh)
|
1993
|
+
blend img, sx, sy, sw, sh, dx, dy, dw, dh, BLEND
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
# Blends image.
|
1997
|
+
#
|
1998
|
+
# @overload blend(sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
1999
|
+
# @overload blend(img, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
2000
|
+
#
|
2001
|
+
# @param img [Image] image for blend source
|
2002
|
+
# @param sx [Numrtic] x position of source region
|
2003
|
+
# @param sy [Numrtic] y position of source region
|
2004
|
+
# @param sw [Numrtic] width of source region
|
2005
|
+
# @param sh [Numrtic] height of source region
|
2006
|
+
# @param dx [Numrtic] x position of destination region
|
2007
|
+
# @param dy [Numrtic] y position of destination region
|
2008
|
+
# @param dw [Numrtic] width of destination region
|
2009
|
+
# @param dh [Numrtic] height of destination region
|
2010
|
+
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE] blend mode
|
2011
|
+
#
|
2012
|
+
# @return [nil] nil
|
2013
|
+
#
|
2014
|
+
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
1694
2015
|
assertDrawing__
|
1695
|
-
|
1696
|
-
@painter__
|
2016
|
+
img ||= self
|
2017
|
+
img.drawImage__ @painter__, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
2018
|
+
end
|
2019
|
+
|
2020
|
+
# Saves screen image to file.
|
2021
|
+
#
|
2022
|
+
# @param filename [String] file name to save image
|
2023
|
+
#
|
2024
|
+
def save(filename)
|
2025
|
+
@window__.canvas_image.save filename
|
1697
2026
|
end
|
1698
2027
|
|
1699
2028
|
# Applies translation matrix to current transformation matrix.
|
@@ -1749,11 +2078,10 @@ module RubySketch
|
|
1749
2078
|
def pushMatrix(&block)
|
1750
2079
|
assertDrawing__
|
1751
2080
|
@matrixStack__.push @painter__.matrix
|
1752
|
-
if block
|
1753
|
-
block.call
|
1754
|
-
popMatrix
|
1755
|
-
end
|
2081
|
+
block.call if block
|
1756
2082
|
nil
|
2083
|
+
ensure
|
2084
|
+
popMatrix if block
|
1757
2085
|
end
|
1758
2086
|
|
1759
2087
|
# Pops the current transformation matrix from stack.
|
@@ -1792,18 +2120,22 @@ module RubySketch
|
|
1792
2120
|
@painter__.clip,
|
1793
2121
|
@painter__.blend_mode,
|
1794
2122
|
@painter__.font,
|
2123
|
+
@painter__.shader,
|
1795
2124
|
@hsbColor__,
|
1796
2125
|
@colorMaxes__,
|
1797
2126
|
@angleScale__,
|
1798
2127
|
@rectMode__,
|
1799
2128
|
@ellipseMode__,
|
1800
|
-
@imageMode__
|
2129
|
+
@imageMode__,
|
2130
|
+
@textAlignH__,
|
2131
|
+
@textAlignV__,
|
2132
|
+
@tint__,
|
2133
|
+
@filter__,
|
1801
2134
|
]
|
1802
|
-
if block
|
1803
|
-
block.call
|
1804
|
-
popStyle
|
1805
|
-
end
|
2135
|
+
block.call if block
|
1806
2136
|
nil
|
2137
|
+
ensure
|
2138
|
+
popStyle if block
|
1807
2139
|
end
|
1808
2140
|
|
1809
2141
|
# Restore style values from the style stack.
|
@@ -1821,12 +2153,17 @@ module RubySketch
|
|
1821
2153
|
@painter__.clip,
|
1822
2154
|
@painter__.blend_mode,
|
1823
2155
|
@painter__.font,
|
2156
|
+
@painter__.shader,
|
1824
2157
|
@hsbColor__,
|
1825
2158
|
@colorMaxes__,
|
1826
2159
|
@angleScale__,
|
1827
2160
|
@rectMode__,
|
1828
2161
|
@ellipseMode__,
|
1829
|
-
@imageMode__
|
2162
|
+
@imageMode__,
|
2163
|
+
@textAlignH__,
|
2164
|
+
@textAlignV__,
|
2165
|
+
@tint__,
|
2166
|
+
@filter__ = @styleStack__.pop
|
1830
2167
|
nil
|
1831
2168
|
end
|
1832
2169
|
|
@@ -1837,10 +2174,9 @@ module RubySketch
|
|
1837
2174
|
def push(&block)
|
1838
2175
|
pushMatrix
|
1839
2176
|
pushStyle
|
1840
|
-
if block
|
1841
|
-
|
1842
|
-
|
1843
|
-
end
|
2177
|
+
block.call if block
|
2178
|
+
ensure
|
2179
|
+
pop if block
|
1844
2180
|
end
|
1845
2181
|
|
1846
2182
|
# Restore styles and transformations from stack.
|
@@ -1857,923 +2193,993 @@ module RubySketch
|
|
1857
2193
|
@image__
|
1858
2194
|
end
|
1859
2195
|
|
2196
|
+
# @private
|
2197
|
+
def drawImage__(painter, *args, **states)
|
2198
|
+
shader = painter.shader || @filter__&.getInternal__
|
2199
|
+
painter.push shader: shader, **states do |_|
|
2200
|
+
painter.image getInternal__, *args
|
2201
|
+
end
|
2202
|
+
end
|
2203
|
+
|
1860
2204
|
# @private
|
1861
2205
|
private def assertDrawing__()
|
1862
2206
|
raise "call beginDraw() before drawing" unless @drawing__
|
1863
2207
|
end
|
1864
2208
|
|
1865
|
-
|
1866
|
-
|
1867
|
-
|
1868
|
-
# Draws graphics into an offscreen buffer
|
1869
|
-
#
|
1870
|
-
class Graphics
|
1871
|
-
|
1872
|
-
include GraphicsContext
|
2209
|
+
#
|
2210
|
+
# Utilities
|
2211
|
+
#
|
1873
2212
|
|
1874
|
-
#
|
2213
|
+
# Returns the absolute number of the value.
|
1875
2214
|
#
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
2215
|
+
# @param value [Numeric] number
|
2216
|
+
#
|
2217
|
+
# @return [Numeric] absolute number
|
2218
|
+
#
|
2219
|
+
def abs(value)
|
2220
|
+
value.abs
|
1879
2221
|
end
|
1880
2222
|
|
1881
|
-
#
|
2223
|
+
# Returns the closest integer number greater than or equal to the value.
|
1882
2224
|
#
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
endDraw
|
1890
|
-
end
|
2225
|
+
# @param value [Numeric] number
|
2226
|
+
#
|
2227
|
+
# @return [Numeric] rounded up number
|
2228
|
+
#
|
2229
|
+
def ceil(value)
|
2230
|
+
value.ceil
|
1891
2231
|
end
|
1892
2232
|
|
1893
|
-
#
|
2233
|
+
# Returns the closest integer number less than or equal to the value.
|
1894
2234
|
#
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
2235
|
+
# @param value [Numeric] number
|
2236
|
+
#
|
2237
|
+
# @return [Numeric] rounded down number
|
2238
|
+
#
|
2239
|
+
def floor(value)
|
2240
|
+
value.floor
|
1899
2241
|
end
|
1900
2242
|
|
1901
|
-
|
1902
|
-
|
2243
|
+
# Returns the closest integer number.
|
2244
|
+
#
|
2245
|
+
# @param value [Numeric] number
|
2246
|
+
#
|
2247
|
+
# @return [Numeric] rounded number
|
2248
|
+
#
|
2249
|
+
def round(value)
|
2250
|
+
value.round
|
2251
|
+
end
|
1903
2252
|
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
2253
|
+
# Returns the natural logarithm (the base-e logarithm) of a number.
|
2254
|
+
#
|
2255
|
+
# @param value [Numeric] number (> 0.0)
|
2256
|
+
#
|
2257
|
+
# @return [Numeric] result number
|
2258
|
+
#
|
2259
|
+
def log(n)
|
2260
|
+
Math.log n
|
2261
|
+
end
|
1907
2262
|
|
1908
|
-
|
2263
|
+
# Returns Euler's number e raised to the power of value.
|
2264
|
+
#
|
2265
|
+
# @param value [Numeric] number
|
2266
|
+
#
|
2267
|
+
# @return [Numeric] result number
|
2268
|
+
#
|
2269
|
+
def exp(n)
|
2270
|
+
Math.exp n
|
2271
|
+
end
|
1909
2272
|
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
2273
|
+
# Returns value raised to the power of exponent.
|
2274
|
+
#
|
2275
|
+
# @param value [Numeric] base number
|
2276
|
+
# @param exponent [Numeric] exponent number
|
2277
|
+
#
|
2278
|
+
# @return [Numeric] value ** exponent
|
2279
|
+
#
|
2280
|
+
def pow(value, exponent)
|
2281
|
+
value ** exponent
|
2282
|
+
end
|
1913
2283
|
|
1914
|
-
#
|
1915
|
-
|
2284
|
+
# Returns squared value.
|
2285
|
+
#
|
2286
|
+
# @param value [Numeric] number
|
2287
|
+
#
|
2288
|
+
# @return [Numeric] squared value
|
2289
|
+
#
|
2290
|
+
def sq(value)
|
2291
|
+
value * value
|
2292
|
+
end
|
1916
2293
|
|
1917
|
-
#
|
1918
|
-
|
1919
|
-
|
2294
|
+
# Returns squared value.
|
2295
|
+
#
|
2296
|
+
# @param value [Numeric] number
|
2297
|
+
#
|
2298
|
+
# @return [Numeric] squared value
|
2299
|
+
#
|
2300
|
+
def sqrt(value)
|
2301
|
+
Math.sqrt value
|
1920
2302
|
end
|
1921
2303
|
|
1922
|
-
#
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
@pointerPos__ =
|
1940
|
-
@pointerPrevPos__ = Rays::Point.new 0
|
1941
|
-
@pointersPressed__ = []
|
1942
|
-
@touches__ = []
|
1943
|
-
@motionGravity__ = createVector 0, 0
|
1944
|
-
|
1945
|
-
@window__.before_draw = proc {beginDraw__}
|
1946
|
-
@window__.after_draw = proc {endDraw__}
|
1947
|
-
|
1948
|
-
drawFrame = -> {
|
1949
|
-
updateCanvas__ @window__.canvas_image, @window__.canvas_painter
|
1950
|
-
begin
|
1951
|
-
push
|
1952
|
-
@drawBlock__.call if @drawBlock__
|
1953
|
-
ensure
|
1954
|
-
pop
|
1955
|
-
@frameCount__ += 1
|
1956
|
-
end
|
1957
|
-
}
|
1958
|
-
|
1959
|
-
@window__.draw = proc do |e|
|
1960
|
-
if @loop__ || @redraw__
|
1961
|
-
@redraw__ = false
|
1962
|
-
drawFrame.call
|
1963
|
-
end
|
1964
|
-
end
|
1965
|
-
|
1966
|
-
updateKeyStates = -> event, pressed {
|
1967
|
-
@key__ = event.chars
|
1968
|
-
@keyCode__ = event.key
|
1969
|
-
if pressed != nil
|
1970
|
-
set, key = @keysPressed__, event.key
|
1971
|
-
pressed ? set.add(key) : set.delete(key)
|
1972
|
-
end
|
1973
|
-
}
|
1974
|
-
|
1975
|
-
mouseButtonMap = {
|
1976
|
-
mouse_left: LEFT,
|
1977
|
-
mouse_right: RIGHT,
|
1978
|
-
mouse_middle: CENTER
|
1979
|
-
}
|
1980
|
-
|
1981
|
-
updatePointerStates = -> event, pressed = nil {
|
1982
|
-
@pointerPrevPos__ = @pointerPos__
|
1983
|
-
@pointerPos__ = event.pos.dup
|
1984
|
-
@touches__ = event.pointers.map {|p| Touch.new(p.id, *p.pos.to_a)}
|
1985
|
-
if pressed != nil
|
1986
|
-
array = @pointersPressed__
|
1987
|
-
event.types
|
1988
|
-
.tap {|types| types.delete :mouse}
|
1989
|
-
.map {|type| mouseButtonMap[type] || type}
|
1990
|
-
.each {|type| pressed ? array.push(type) : array.delete(type)}
|
1991
|
-
end
|
1992
|
-
}
|
1993
|
-
|
1994
|
-
@window__.key_down = proc do |e|
|
1995
|
-
updateKeyStates.call e, true
|
1996
|
-
@keyPressedBlock__&.call
|
1997
|
-
@keyTypedBlock__&.call if @key__ && !@key__.empty?
|
1998
|
-
end
|
1999
|
-
|
2000
|
-
@window__.key_up = proc do |e|
|
2001
|
-
updateKeyStates.call e, false
|
2002
|
-
@keyReleasedBlock__&.call
|
2003
|
-
end
|
2004
|
-
|
2005
|
-
@window__.pointer_down = proc do |e|
|
2006
|
-
updatePointerStates.call e, true
|
2007
|
-
@pointerDownStartPos__ = @pointerPos__.dup
|
2008
|
-
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
2009
|
-
end
|
2010
|
-
|
2011
|
-
@window__.pointer_up = proc do |e|
|
2012
|
-
updatePointerStates.call e, false
|
2013
|
-
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
2014
|
-
if startPos = @pointerDownStartPos__
|
2015
|
-
@mouseClickedBlock__&.call if (@pointerPos__ - startPos).length < 3
|
2016
|
-
@pointerDownStartPos__ = nil
|
2017
|
-
end
|
2018
|
-
end
|
2019
|
-
|
2020
|
-
@window__.pointer_move = proc do |e|
|
2021
|
-
updatePointerStates.call e
|
2022
|
-
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
2023
|
-
end
|
2024
|
-
|
2025
|
-
@window__.pointer_drag = proc do |e|
|
2026
|
-
updatePointerStates.call e
|
2027
|
-
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
2028
|
-
end
|
2029
|
-
|
2030
|
-
@window__.motion = proc do |e|
|
2031
|
-
@motionGravity__ = createVector(*e.gravity.to_a(3))
|
2032
|
-
@motionBlock__&.call
|
2304
|
+
# Returns the magnitude (or length) of a vector.
|
2305
|
+
#
|
2306
|
+
# @overload mag(x, y)
|
2307
|
+
# @overload mag(x, y, z)
|
2308
|
+
#
|
2309
|
+
# @param x [Numeric] x of point
|
2310
|
+
# @param y [Numeric] y of point
|
2311
|
+
# @param z [Numeric] z of point
|
2312
|
+
#
|
2313
|
+
# @return [Numeric] magnitude
|
2314
|
+
#
|
2315
|
+
def mag(*args)
|
2316
|
+
x, y, z = *args
|
2317
|
+
case args.size
|
2318
|
+
when 2 then Math.sqrt x * x + y * y
|
2319
|
+
when 3 then Math.sqrt x * x + y * y + z * z
|
2320
|
+
else raise ArgumentError
|
2033
2321
|
end
|
2034
2322
|
end
|
2035
2323
|
|
2036
|
-
#
|
2324
|
+
# Returns distance between 2 points.
|
2037
2325
|
#
|
2038
|
-
# @
|
2326
|
+
# @overload dist(x1, y1, x2, y2)
|
2327
|
+
# @overload dist(x1, y1, z1, x2, y2, z2)
|
2039
2328
|
#
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2329
|
+
# @param x1 [Numeric] x of first point
|
2330
|
+
# @param y1 [Numeric] y of first point
|
2331
|
+
# @param z1 [Numeric] z of first point
|
2332
|
+
# @param x2 [Numeric] x of second point
|
2333
|
+
# @param y2 [Numeric] y of second point
|
2334
|
+
# @param z2 [Numeric] z of second point
|
2335
|
+
#
|
2336
|
+
# @return [Numeric] distance between 2 points
|
2337
|
+
#
|
2338
|
+
def dist(*args)
|
2339
|
+
case args.size
|
2340
|
+
when 4
|
2341
|
+
x1, y1, x2, y2 = *args
|
2342
|
+
xx, yy = x2 - x1, y2 - y1
|
2343
|
+
Math.sqrt xx * xx + yy * yy
|
2344
|
+
when 3
|
2345
|
+
x1, y1, z1, x2, y2, z2 = *args
|
2346
|
+
xx, yy, zz = x2 - x1, y2 - y1, z2 - z1
|
2347
|
+
Math.sqrt xx * xx + yy * yy + zz * zz
|
2348
|
+
else raise ArgumentError
|
2349
|
+
end
|
2043
2350
|
end
|
2044
2351
|
|
2045
|
-
#
|
2352
|
+
# Normalize the value from range start..stop into 0..1.
|
2046
2353
|
#
|
2047
|
-
# @
|
2354
|
+
# @param value [Numeric] number to be normalized
|
2355
|
+
# @param start [Numeric] lower bound of the range
|
2356
|
+
# @param stop [Numeric] upper bound of the range
|
2048
2357
|
#
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2358
|
+
# @return [Numeric] normalized value between 0..1
|
2359
|
+
#
|
2360
|
+
def norm(value, start, stop)
|
2361
|
+
(value.to_f - start.to_f) / (stop.to_f - start.to_f)
|
2052
2362
|
end
|
2053
2363
|
|
2054
|
-
#
|
2364
|
+
# Returns the interpolated number between range start..stop.
|
2055
2365
|
#
|
2056
|
-
# @
|
2366
|
+
# @param start [Numeric] lower bound of the range
|
2367
|
+
# @param stop [Numeric] upper bound of the range
|
2368
|
+
# @param amount [Numeric] amount to interpolate
|
2057
2369
|
#
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2370
|
+
# @return [Numeric] interporated number
|
2371
|
+
#
|
2372
|
+
def lerp(start, stop, amount)
|
2373
|
+
start + (stop - start) * amount
|
2061
2374
|
end
|
2062
2375
|
|
2063
|
-
#
|
2376
|
+
# Maps a number from range start1..stop1 to range start2..stop2.
|
2064
2377
|
#
|
2065
|
-
# @
|
2378
|
+
# @param value [Numeric] number to be mapped
|
2379
|
+
# @param start1 [Numeric] lower bound of the range1
|
2380
|
+
# @param stop1 [Numeric] upper bound of the range1
|
2381
|
+
# @param start2 [Numeric] lower bound of the range2
|
2382
|
+
# @param stop2 [Numeric] upper bound of the range2
|
2066
2383
|
#
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2384
|
+
# @return [Numeric] mapped number
|
2385
|
+
#
|
2386
|
+
def map(value, start1, stop1, start2, stop2)
|
2387
|
+
lerp start2, stop2, norm(value, start1, stop1)
|
2070
2388
|
end
|
2071
2389
|
|
2072
|
-
#
|
2390
|
+
# Returns minimum value.
|
2073
2391
|
#
|
2074
|
-
# @
|
2392
|
+
# @overload min(a, b)
|
2393
|
+
# @overload min(a, b, c)
|
2394
|
+
# @overload min(array)
|
2075
2395
|
#
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2396
|
+
# @param a [Numeric] value to compare
|
2397
|
+
# @param b [Numeric] value to compare
|
2398
|
+
# @param c [Numeric] value to compare
|
2399
|
+
# @param array [Numeric] values to compare
|
2400
|
+
#
|
2401
|
+
# @return [Numeric] minimum value
|
2402
|
+
#
|
2403
|
+
def min(*args)
|
2404
|
+
args.flatten.min
|
2079
2405
|
end
|
2080
2406
|
|
2081
|
-
#
|
2407
|
+
# Returns maximum value.
|
2082
2408
|
#
|
2083
|
-
# @
|
2409
|
+
# @overload max(a, b)
|
2410
|
+
# @overload max(a, b, c)
|
2411
|
+
# @overload max(array)
|
2084
2412
|
#
|
2085
|
-
|
2086
|
-
|
2087
|
-
|
2413
|
+
# @param a [Numeric] value to compare
|
2414
|
+
# @param b [Numeric] value to compare
|
2415
|
+
# @param c [Numeric] value to compare
|
2416
|
+
# @param array [Numeric] values to compare
|
2417
|
+
#
|
2418
|
+
# @return [Numeric] maximum value
|
2419
|
+
#
|
2420
|
+
def max(*args)
|
2421
|
+
args.flatten.max
|
2088
2422
|
end
|
2089
2423
|
|
2090
|
-
#
|
2424
|
+
# Constrains the number between min..max.
|
2091
2425
|
#
|
2092
|
-
# @
|
2426
|
+
# @param value [Numeric] number to be constrained
|
2427
|
+
# @param min [Numeric] lower bound of the range
|
2428
|
+
# @param max [Numeric] upper bound of the range
|
2093
2429
|
#
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2430
|
+
# @return [Numeric] constrained number
|
2431
|
+
#
|
2432
|
+
def constrain(value, min, max)
|
2433
|
+
value < min ? min : (value > max ? max : value)
|
2097
2434
|
end
|
2098
2435
|
|
2099
|
-
#
|
2436
|
+
# Converts degree to radian.
|
2100
2437
|
#
|
2101
|
-
# @
|
2438
|
+
# @param degree [Numeric] degree to convert
|
2102
2439
|
#
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2440
|
+
# @return [Numeric] radian
|
2441
|
+
#
|
2442
|
+
def radians(degree)
|
2443
|
+
degree * DEG2RAD__
|
2106
2444
|
end
|
2107
2445
|
|
2108
|
-
#
|
2446
|
+
# Converts radian to degree.
|
2109
2447
|
#
|
2110
|
-
# @
|
2448
|
+
# @param radian [Numeric] radian to convert
|
2111
2449
|
#
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2450
|
+
# @return [Numeric] degree
|
2451
|
+
#
|
2452
|
+
def degrees(radian)
|
2453
|
+
radian * RAD2DEG__
|
2115
2454
|
end
|
2116
2455
|
|
2117
|
-
#
|
2456
|
+
# Returns the sine of an angle.
|
2118
2457
|
#
|
2119
|
-
# @
|
2458
|
+
# @param angle [Numeric] angle in radians
|
2120
2459
|
#
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2460
|
+
# @return [Numeric] the sine
|
2461
|
+
#
|
2462
|
+
def sin(angle)
|
2463
|
+
Math.sin angle
|
2124
2464
|
end
|
2125
2465
|
|
2126
|
-
#
|
2466
|
+
# Returns the cosine of an angle.
|
2127
2467
|
#
|
2128
|
-
# @
|
2468
|
+
# @param angle [Numeric] angle in radians
|
2129
2469
|
#
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2470
|
+
# @return [Numeric] the cosine
|
2471
|
+
#
|
2472
|
+
def cos(angle)
|
2473
|
+
Math.cos angle
|
2133
2474
|
end
|
2134
2475
|
|
2135
|
-
#
|
2476
|
+
# Returns the ratio of the sine and cosine of an angle.
|
2136
2477
|
#
|
2137
|
-
# @
|
2478
|
+
# @param angle [Numeric] angle in radians
|
2138
2479
|
#
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2480
|
+
# @return [Numeric] the tangent
|
2481
|
+
#
|
2482
|
+
def tan(angle)
|
2483
|
+
Math.tan angle
|
2142
2484
|
end
|
2143
2485
|
|
2144
|
-
#
|
2486
|
+
# Returns the inverse of sin().
|
2145
2487
|
#
|
2146
|
-
# @
|
2488
|
+
# @param value [Numeric] value for calculation
|
2147
2489
|
#
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2490
|
+
# @return [Numeric] the arc sine
|
2491
|
+
#
|
2492
|
+
def asin(value)
|
2493
|
+
Math.asin value
|
2151
2494
|
end
|
2152
2495
|
|
2153
|
-
#
|
2496
|
+
# Returns the inverse of cos().
|
2154
2497
|
#
|
2155
|
-
# @
|
2498
|
+
# @param value [Numeric] value for calculation
|
2156
2499
|
#
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2500
|
+
# @return [Numeric] the arc cosine
|
2501
|
+
#
|
2502
|
+
def acos(value)
|
2503
|
+
Math.acos value
|
2160
2504
|
end
|
2161
2505
|
|
2162
|
-
#
|
2506
|
+
# Returns the inverse of tan().
|
2163
2507
|
#
|
2164
|
-
# @param
|
2165
|
-
# @param height [Integer] new height
|
2166
|
-
# @param pixelDensity [Numeric] new pixel density
|
2508
|
+
# @param value [Numeric] value for valculation
|
2167
2509
|
#
|
2168
|
-
# @return [
|
2510
|
+
# @return [Numeric] the arc tangent
|
2169
2511
|
#
|
2170
|
-
def
|
2171
|
-
|
2172
|
-
nil
|
2512
|
+
def atan(value)
|
2513
|
+
Math.atan value
|
2173
2514
|
end
|
2174
2515
|
|
2175
|
-
#
|
2516
|
+
# Returns the angle from a specified point.
|
2176
2517
|
#
|
2177
|
-
# @param
|
2178
|
-
# @param
|
2179
|
-
# @param pixelDensity [Numeric] new pixel density
|
2518
|
+
# @param y [Numeric] y of the point
|
2519
|
+
# @param x [Numeric] x of the point
|
2180
2520
|
#
|
2181
|
-
# @return [
|
2521
|
+
# @return [Numeric] the angle in radians
|
2182
2522
|
#
|
2183
|
-
def
|
2184
|
-
|
2185
|
-
nil
|
2523
|
+
def atan2(y, x)
|
2524
|
+
Math.atan2 y, x
|
2186
2525
|
end
|
2187
2526
|
|
2188
|
-
#
|
2527
|
+
# Returns the perlin noise value.
|
2189
2528
|
#
|
2190
|
-
# @
|
2529
|
+
# @overload noise(x)
|
2530
|
+
# @overload noise(x, y)
|
2531
|
+
# @overload noise(x, y, z)
|
2191
2532
|
#
|
2192
|
-
# @
|
2533
|
+
# @param x [Numeric] horizontal point in noise space
|
2534
|
+
# @param y [Numeric] vertical point in noise space
|
2535
|
+
# @param z [Numeric] depth point in noise space
|
2193
2536
|
#
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2537
|
+
# @return [Numeric] noise value (0.0..1.0)
|
2538
|
+
#
|
2539
|
+
def noise(x, y = 0, z = 0)
|
2540
|
+
Rays.perlin(x, y, z) / 2.0 + 0.5
|
2197
2541
|
end
|
2198
2542
|
|
2199
|
-
#
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2543
|
+
# Returns a random number in range low...high
|
2544
|
+
#
|
2545
|
+
# @overload random()
|
2546
|
+
# @overload random(high)
|
2547
|
+
# @overload random(low, high)
|
2548
|
+
# @overload random(choices)
|
2549
|
+
#
|
2550
|
+
# @param low [Numeric] lower limit
|
2551
|
+
# @param high [Numeric] upper limit
|
2552
|
+
# @param choices [Array] array to choose from
|
2553
|
+
#
|
2554
|
+
# @return [Float] random number
|
2555
|
+
#
|
2556
|
+
def random(*args)
|
2557
|
+
return args.first.sample if args.first.kind_of? Array
|
2558
|
+
high, low = args.reverse
|
2559
|
+
rand (low || 0).to_f...(high || 1).to_f
|
2212
2560
|
end
|
2213
2561
|
|
2214
|
-
#
|
2562
|
+
# Creates a new vector.
|
2215
2563
|
#
|
2216
|
-
# @
|
2564
|
+
# @overload createVector()
|
2565
|
+
# @overload createVector(x, y)
|
2566
|
+
# @overload createVector(x, y, z)
|
2217
2567
|
#
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2222
|
-
# Returns window width.
|
2568
|
+
# @param x [Numeric] x of new vector
|
2569
|
+
# @param y [Numeric] y of new vector
|
2570
|
+
# @param z [Numeric] z of new vector
|
2223
2571
|
#
|
2224
|
-
# @return [
|
2572
|
+
# @return [Vector] new vector
|
2225
2573
|
#
|
2226
|
-
def
|
2227
|
-
|
2574
|
+
def createVector(*args)
|
2575
|
+
Vector.new(*args, context: self)
|
2228
2576
|
end
|
2229
2577
|
|
2230
|
-
#
|
2578
|
+
# Creates a new image.
|
2231
2579
|
#
|
2232
|
-
# @
|
2580
|
+
# @overload createImage(w, h)
|
2581
|
+
# @overload createImage(w, h, format)
|
2233
2582
|
#
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
|
2238
|
-
# Returns number of frames since program started.
|
2583
|
+
# @param w [Numeric] width of new image
|
2584
|
+
# @param h [Numeric] height of new image
|
2585
|
+
# @param format [RGB, RGBA] image format
|
2239
2586
|
#
|
2240
|
-
# @return [
|
2587
|
+
# @return [Image] new image
|
2241
2588
|
#
|
2242
|
-
def
|
2243
|
-
|
2589
|
+
def createImage(w, h, format = RGBA)
|
2590
|
+
colorspace = {RGB => Rays::RGB, RGBA => Rays::RGBA}[format]
|
2591
|
+
raise ArgumentError, "Unknown image format" unless colorspace
|
2592
|
+
Image.new Rays::Image.new(w, h, colorspace).paint {background 0, 0}
|
2244
2593
|
end
|
2245
2594
|
|
2246
|
-
#
|
2595
|
+
# Creates a new off-screen graphics context object.
|
2247
2596
|
#
|
2248
|
-
# @
|
2597
|
+
# @param width [Numeric] width of graphics image
|
2598
|
+
# @param height [Numeric] height of graphics image
|
2249
2599
|
#
|
2250
|
-
|
2251
|
-
|
2600
|
+
# @return [Graphics] graphics object
|
2601
|
+
#
|
2602
|
+
def createGraphics(width, height)
|
2603
|
+
Graphics.new width, height
|
2252
2604
|
end
|
2253
2605
|
|
2254
|
-
#
|
2606
|
+
# Creates a shader object.
|
2255
2607
|
#
|
2256
|
-
# @
|
2608
|
+
# @overload createShader(vertPath, fragPath)
|
2609
|
+
# @overload createShader(vertSource, fragSource)
|
2257
2610
|
#
|
2258
|
-
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
# Returns the last key code that was pressed or released.
|
2611
|
+
# @param vertPath [String] vertex shader file path
|
2612
|
+
# @param fragPath [String] fragment shader file path
|
2613
|
+
# @param vertSource [String] vertex shader source
|
2614
|
+
# @param fragSource [String] fragment shader source
|
2263
2615
|
#
|
2264
|
-
# @return [
|
2616
|
+
# @return [Shader] shader object
|
2265
2617
|
#
|
2266
|
-
def
|
2267
|
-
|
2618
|
+
def createShader(vert, frag)
|
2619
|
+
vert = File.read if vert && File.exist?(vert)
|
2620
|
+
frag = File.read if frag && File.exist?(frag)
|
2621
|
+
Shader.new vert, frag
|
2268
2622
|
end
|
2269
2623
|
|
2270
|
-
#
|
2624
|
+
# Creates a camera object as a video input device.
|
2271
2625
|
#
|
2272
|
-
# @return [
|
2626
|
+
# @return [Capture] camera object
|
2273
2627
|
#
|
2274
|
-
def
|
2275
|
-
|
2628
|
+
def createCapture(*args)
|
2629
|
+
Capture.new(*args)
|
2276
2630
|
end
|
2277
2631
|
|
2278
|
-
#
|
2632
|
+
# Loads image.
|
2279
2633
|
#
|
2280
|
-
# @
|
2634
|
+
# @param filename [String] file name to load image
|
2635
|
+
# @param extension [String] type of image to load (ex. 'png')
|
2281
2636
|
#
|
2282
|
-
|
2283
|
-
|
2637
|
+
# @return [Image] loaded image object
|
2638
|
+
#
|
2639
|
+
def loadImage(filename, extension = nil)
|
2640
|
+
filename = getImage__ filename, extension if filename =~ %r|^https?://|
|
2641
|
+
Image.new Rays::Image.load filename
|
2284
2642
|
end
|
2285
2643
|
|
2286
|
-
#
|
2644
|
+
# Loads shader file.
|
2287
2645
|
#
|
2288
|
-
# @
|
2646
|
+
# @overload loadShader(fragPath)
|
2647
|
+
# @overload loadShader(fragPath, vertPath)
|
2289
2648
|
#
|
2290
|
-
|
2291
|
-
|
2292
|
-
end
|
2293
|
-
|
2294
|
-
# Returns mouse y position in previous frame
|
2649
|
+
# @param fragPath [String] fragment shader file path
|
2650
|
+
# @param vertPath [String] vertex shader file path
|
2295
2651
|
#
|
2296
|
-
# @return [
|
2652
|
+
# @return [Shader] loaded shader object
|
2297
2653
|
#
|
2298
|
-
def
|
2299
|
-
|
2654
|
+
def loadShader(fragPath, vertPath = nil)
|
2655
|
+
createShader vertPath, fragPath
|
2300
2656
|
end
|
2301
2657
|
|
2302
|
-
#
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2658
|
+
# @private
|
2659
|
+
private def getImage__(uri, ext)
|
2660
|
+
ext ||= File.extname uri
|
2661
|
+
raise "unsupported image type -- #{ext}" unless ext =~ /^\.?(png|jpg|gif)$/i
|
2662
|
+
|
2663
|
+
tmpdir = tmpdir__
|
2664
|
+
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2665
|
+
path = path.sub_ext ext
|
2666
|
+
|
2667
|
+
unless path.file?
|
2668
|
+
URI.open uri do |input|
|
2669
|
+
input.set_encoding nil# disable default_internal
|
2670
|
+
tmpdir.mkdir unless tmpdir.directory?
|
2671
|
+
path.open('w') do |output|
|
2672
|
+
output.set_encoding Encoding::ASCII_8BIT
|
2673
|
+
while buf = input.read(2 ** 16)
|
2674
|
+
output.write buf
|
2675
|
+
end
|
2676
|
+
end
|
2677
|
+
end
|
2678
|
+
end
|
2679
|
+
path.to_s
|
2308
2680
|
end
|
2309
2681
|
|
2310
|
-
#
|
2311
|
-
|
2312
|
-
|
2313
|
-
#
|
2314
|
-
def touches()
|
2315
|
-
@touches__
|
2682
|
+
# @private
|
2683
|
+
private def tmpdir__()
|
2684
|
+
Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
2316
2685
|
end
|
2317
2686
|
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2687
|
+
end# GraphicsContext
|
2688
|
+
|
2689
|
+
|
2690
|
+
# Draws graphics into an offscreen buffer
|
2691
|
+
#
|
2692
|
+
class Graphics
|
2693
|
+
|
2694
|
+
include GraphicsContext
|
2695
|
+
|
2696
|
+
# Initialize graphics object.
|
2321
2697
|
#
|
2322
|
-
def
|
2323
|
-
|
2698
|
+
def initialize(width, height)
|
2699
|
+
image = Rays::Image.new width, height
|
2700
|
+
init__ image, image.painter
|
2324
2701
|
end
|
2325
2702
|
|
2326
|
-
#
|
2327
|
-
#
|
2328
|
-
# @return [nil] nil
|
2703
|
+
# Start drawing.
|
2329
2704
|
#
|
2330
|
-
def
|
2331
|
-
|
2705
|
+
def beginDraw(&block)
|
2706
|
+
beginDraw__
|
2707
|
+
@painter__.__send__ :begin_paint
|
2708
|
+
push
|
2709
|
+
if block
|
2710
|
+
block.call
|
2711
|
+
endDraw
|
2712
|
+
end
|
2332
2713
|
end
|
2333
2714
|
|
2334
|
-
#
|
2335
|
-
#
|
2336
|
-
# @return [nil] nil
|
2715
|
+
# End drawing.
|
2337
2716
|
#
|
2338
|
-
def
|
2339
|
-
|
2717
|
+
def endDraw()
|
2718
|
+
pop
|
2719
|
+
@painter__.__send__ :end_paint
|
2720
|
+
endDraw__
|
2721
|
+
end
|
2722
|
+
|
2723
|
+
end# Graphics
|
2724
|
+
|
2725
|
+
|
2726
|
+
# Processing context
|
2727
|
+
#
|
2728
|
+
class Context
|
2729
|
+
|
2730
|
+
include GraphicsContext
|
2731
|
+
|
2732
|
+
Vector = Processing::Vector
|
2733
|
+
Capture = Processing::Capture
|
2734
|
+
Graphics = Processing::Graphics
|
2735
|
+
Shader = Processing::Shader
|
2736
|
+
|
2737
|
+
# @private
|
2738
|
+
@@context__ = nil
|
2739
|
+
|
2740
|
+
# @private
|
2741
|
+
def self.context__()
|
2742
|
+
@@context__
|
2340
2743
|
end
|
2341
2744
|
|
2342
|
-
#
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
|
2745
|
+
# @private
|
2746
|
+
def initialize(window)
|
2747
|
+
@@context__ = self
|
2748
|
+
|
2749
|
+
tmpdir__.tap {|dir| FileUtils.rm_r dir.to_s if dir.directory?}
|
2750
|
+
|
2751
|
+
@window__ = window
|
2752
|
+
init__(
|
2753
|
+
@window__.canvas_image,
|
2754
|
+
@window__.canvas_painter.paint {background 0.8})
|
2755
|
+
|
2756
|
+
@loop__ = true
|
2757
|
+
@redraw__ = false
|
2758
|
+
@frameCount__ = 0
|
2759
|
+
@key__ = nil
|
2760
|
+
@keyCode__ = nil
|
2761
|
+
@keysPressed__ = Set.new
|
2762
|
+
@pointerPos__ =
|
2763
|
+
@pointerPrevPos__ = Rays::Point.new 0
|
2764
|
+
@pointersPressed__ = []
|
2765
|
+
@touches__ = []
|
2766
|
+
@motionGravity__ = createVector 0, 0
|
2767
|
+
|
2768
|
+
@window__.before_draw = proc {beginDraw__}
|
2769
|
+
@window__.after_draw = proc {endDraw__}
|
2770
|
+
@window__.update_canvas = proc {|i, p| updateCanvas__ i, p}
|
2771
|
+
|
2772
|
+
@window__.instance_variable_set :@context, self
|
2773
|
+
def @window__.draw_screen(painter)
|
2774
|
+
@context.drawImage__ painter
|
2775
|
+
end
|
2776
|
+
|
2777
|
+
drawFrame = -> {
|
2778
|
+
begin
|
2779
|
+
push
|
2780
|
+
@drawBlock__.call if @drawBlock__
|
2781
|
+
ensure
|
2782
|
+
pop
|
2783
|
+
@frameCount__ += 1
|
2784
|
+
end
|
2785
|
+
}
|
2786
|
+
|
2787
|
+
@window__.draw = proc do |e|
|
2788
|
+
if @loop__ || @redraw__
|
2789
|
+
@redraw__ = false
|
2790
|
+
drawFrame.call
|
2791
|
+
end
|
2792
|
+
end
|
2793
|
+
|
2794
|
+
updateKeyStates = -> event, pressed {
|
2795
|
+
@key__ = event.chars
|
2796
|
+
@keyCode__ = event.key
|
2797
|
+
if pressed != nil
|
2798
|
+
set, key = @keysPressed__, event.key
|
2799
|
+
pressed ? set.add(key) : set.delete(key)
|
2800
|
+
end
|
2801
|
+
}
|
2802
|
+
|
2803
|
+
mouseButtonMap = {
|
2804
|
+
mouse_left: LEFT,
|
2805
|
+
mouse_right: RIGHT,
|
2806
|
+
mouse_middle: CENTER
|
2807
|
+
}
|
2808
|
+
|
2809
|
+
updatePointerStates = -> event, pressed = nil {
|
2810
|
+
@pointerPrevPos__ = @pointerPos__
|
2811
|
+
@pointerPos__ = event.pos.dup
|
2812
|
+
@touches__ = event.pointers.map {|p| Touch.new(p.id, *p.pos.to_a)}
|
2813
|
+
if pressed != nil
|
2814
|
+
array = @pointersPressed__
|
2815
|
+
event.types
|
2816
|
+
.tap {|types| types.delete :mouse}
|
2817
|
+
.map {|type| mouseButtonMap[type] || type}
|
2818
|
+
.each {|type| pressed ? array.push(type) : array.delete(type)}
|
2819
|
+
end
|
2820
|
+
}
|
2821
|
+
|
2822
|
+
@window__.key_down = proc do |e|
|
2823
|
+
updateKeyStates.call e, true
|
2824
|
+
@keyPressedBlock__&.call
|
2825
|
+
@keyTypedBlock__&.call if @key__ && !@key__.empty?
|
2826
|
+
end
|
2827
|
+
|
2828
|
+
@window__.key_up = proc do |e|
|
2829
|
+
updateKeyStates.call e, false
|
2830
|
+
@keyReleasedBlock__&.call
|
2831
|
+
end
|
2349
2832
|
|
2350
|
-
|
2351
|
-
|
2352
|
-
|
2833
|
+
@window__.pointer_down = proc do |e|
|
2834
|
+
updatePointerStates.call e, true
|
2835
|
+
@pointerDownStartPos__ = @pointerPos__.dup
|
2836
|
+
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
2837
|
+
end
|
2353
2838
|
|
2354
|
-
|
2355
|
-
|
2356
|
-
|
2357
|
-
|
2358
|
-
|
2359
|
-
|
2360
|
-
|
2361
|
-
|
2362
|
-
end
|
2839
|
+
@window__.pointer_up = proc do |e|
|
2840
|
+
updatePointerStates.call e, false
|
2841
|
+
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
2842
|
+
if startPos = @pointerDownStartPos__
|
2843
|
+
@mouseClickedBlock__&.call if (@pointerPos__ - startPos).length < 3
|
2844
|
+
@pointerDownStartPos__ = nil
|
2845
|
+
end
|
2846
|
+
end
|
2363
2847
|
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
# @return [Numeric] rounded up number
|
2369
|
-
#
|
2370
|
-
def ceil(value)
|
2371
|
-
value.ceil
|
2372
|
-
end
|
2848
|
+
@window__.pointer_move = proc do |e|
|
2849
|
+
updatePointerStates.call e
|
2850
|
+
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
2851
|
+
end
|
2373
2852
|
|
2374
|
-
|
2375
|
-
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
|
2381
|
-
|
2853
|
+
@window__.pointer_drag = proc do |e|
|
2854
|
+
updatePointerStates.call e
|
2855
|
+
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
2856
|
+
end
|
2857
|
+
|
2858
|
+
@window__.motion = proc do |e|
|
2859
|
+
@motionGravity__ = createVector(*e.gravity.to_a(3))
|
2860
|
+
@motionBlock__&.call
|
2861
|
+
end
|
2382
2862
|
end
|
2383
2863
|
|
2384
|
-
#
|
2385
|
-
#
|
2386
|
-
# @param value [Numeric] number
|
2864
|
+
# Defines setup block.
|
2387
2865
|
#
|
2388
|
-
# @return [
|
2866
|
+
# @return [nil] nil
|
2389
2867
|
#
|
2390
|
-
def
|
2391
|
-
|
2868
|
+
def setup(&block)
|
2869
|
+
@window__.setup = block
|
2870
|
+
nil
|
2392
2871
|
end
|
2393
2872
|
|
2394
|
-
#
|
2395
|
-
#
|
2396
|
-
# @param value [Numeric] number (> 0.0)
|
2873
|
+
# Defines draw block.
|
2397
2874
|
#
|
2398
|
-
# @return [
|
2875
|
+
# @return [nil] nil
|
2399
2876
|
#
|
2400
|
-
def
|
2401
|
-
|
2877
|
+
def draw(&block)
|
2878
|
+
@drawBlock__ = block if block
|
2879
|
+
nil
|
2402
2880
|
end
|
2403
2881
|
|
2404
|
-
#
|
2405
|
-
#
|
2406
|
-
# @param value [Numeric] number
|
2882
|
+
# Defines keyPressed block.
|
2407
2883
|
#
|
2408
|
-
# @return [
|
2884
|
+
# @return [Boolean] is any key pressed or not
|
2409
2885
|
#
|
2410
|
-
def
|
2411
|
-
|
2886
|
+
def keyPressed(&block)
|
2887
|
+
@keyPressedBlock__ = block if block
|
2888
|
+
not @keysPressed__.empty?
|
2412
2889
|
end
|
2413
2890
|
|
2414
|
-
#
|
2415
|
-
#
|
2416
|
-
# @param value [Numeric] base number
|
2417
|
-
# @param exponent [Numeric] exponent number
|
2891
|
+
# Defines keyReleased block.
|
2418
2892
|
#
|
2419
|
-
# @return [
|
2893
|
+
# @return [nil] nil
|
2420
2894
|
#
|
2421
|
-
def
|
2422
|
-
|
2895
|
+
def keyReleased(&block)
|
2896
|
+
@keyReleasedBlock__ = block if block
|
2897
|
+
nil
|
2423
2898
|
end
|
2424
2899
|
|
2425
|
-
#
|
2426
|
-
#
|
2427
|
-
# @param value [Numeric] number
|
2900
|
+
# Defines keyTyped block.
|
2428
2901
|
#
|
2429
|
-
# @return [
|
2902
|
+
# @return [nil] nil
|
2430
2903
|
#
|
2431
|
-
def
|
2432
|
-
|
2904
|
+
def keyTyped(&block)
|
2905
|
+
@keyTypedBlock__ = block if block
|
2906
|
+
nil
|
2433
2907
|
end
|
2434
2908
|
|
2435
|
-
#
|
2436
|
-
#
|
2437
|
-
# @param value [Numeric] number
|
2909
|
+
# Defines mousePressed block.
|
2438
2910
|
#
|
2439
|
-
# @return [
|
2911
|
+
# @return [Boolean] is any mouse button pressed or not
|
2440
2912
|
#
|
2441
|
-
def
|
2442
|
-
|
2913
|
+
def mousePressed(&block)
|
2914
|
+
@mousePressedBlock__ = block if block
|
2915
|
+
not @pointersPressed__.empty?
|
2443
2916
|
end
|
2444
2917
|
|
2445
|
-
#
|
2446
|
-
#
|
2447
|
-
# @overload mag(x, y)
|
2448
|
-
# @overload mag(x, y, z)
|
2449
|
-
#
|
2450
|
-
# @param x [Numeric] x of point
|
2451
|
-
# @param y [Numeric] y of point
|
2452
|
-
# @param z [Numeric] z of point
|
2918
|
+
# Defines mouseReleased block.
|
2453
2919
|
#
|
2454
|
-
# @return [
|
2920
|
+
# @return [nil] nil
|
2455
2921
|
#
|
2456
|
-
def
|
2457
|
-
|
2458
|
-
|
2459
|
-
when 2 then Math.sqrt x * x + y * y
|
2460
|
-
when 3 then Math.sqrt x * x + y * y + z * z
|
2461
|
-
else raise ArgumentError
|
2462
|
-
end
|
2922
|
+
def mouseReleased(&block)
|
2923
|
+
@mouseReleasedBlock__ = block if block
|
2924
|
+
nil
|
2463
2925
|
end
|
2464
2926
|
|
2465
|
-
#
|
2466
|
-
#
|
2467
|
-
# @overload dist(x1, y1, x2, y2)
|
2468
|
-
# @overload dist(x1, y1, z1, x2, y2, z2)
|
2469
|
-
#
|
2470
|
-
# @param x1 [Numeric] x of first point
|
2471
|
-
# @param y1 [Numeric] y of first point
|
2472
|
-
# @param z1 [Numeric] z of first point
|
2473
|
-
# @param x2 [Numeric] x of second point
|
2474
|
-
# @param y2 [Numeric] y of second point
|
2475
|
-
# @param z2 [Numeric] z of second point
|
2927
|
+
# Defines mouseMoved block.
|
2476
2928
|
#
|
2477
|
-
# @return [
|
2929
|
+
# @return [nil] nil
|
2478
2930
|
#
|
2479
|
-
def
|
2480
|
-
|
2481
|
-
|
2482
|
-
x1, y1, x2, y2 = *args
|
2483
|
-
xx, yy = x2 - x1, y2 - y1
|
2484
|
-
Math.sqrt xx * xx + yy * yy
|
2485
|
-
when 3
|
2486
|
-
x1, y1, z1, x2, y2, z2 = *args
|
2487
|
-
xx, yy, zz = x2 - x1, y2 - y1, z2 - z1
|
2488
|
-
Math.sqrt xx * xx + yy * yy + zz * zz
|
2489
|
-
else raise ArgumentError
|
2490
|
-
end
|
2931
|
+
def mouseMoved(&block)
|
2932
|
+
@mouseMovedBlock__ = block if block
|
2933
|
+
nil
|
2491
2934
|
end
|
2492
2935
|
|
2493
|
-
#
|
2494
|
-
#
|
2495
|
-
# @param value [Numeric] number to be normalized
|
2496
|
-
# @param start [Numeric] lower bound of the range
|
2497
|
-
# @param stop [Numeric] upper bound of the range
|
2936
|
+
# Defines mouseDragged block.
|
2498
2937
|
#
|
2499
|
-
# @return [
|
2938
|
+
# @return [nil] nil
|
2500
2939
|
#
|
2501
|
-
def
|
2502
|
-
|
2940
|
+
def mouseDragged(&block)
|
2941
|
+
@mouseDraggedBlock__ = block if block
|
2942
|
+
nil
|
2503
2943
|
end
|
2504
2944
|
|
2505
|
-
#
|
2506
|
-
#
|
2507
|
-
# @param start [Numeric] lower bound of the range
|
2508
|
-
# @param stop [Numeric] upper bound of the range
|
2509
|
-
# @param amount [Numeric] amount to interpolate
|
2945
|
+
# Defines mouseClicked block.
|
2510
2946
|
#
|
2511
|
-
# @return [
|
2947
|
+
# @return [nil] nil
|
2512
2948
|
#
|
2513
|
-
def
|
2514
|
-
|
2949
|
+
def mouseClicked(&block)
|
2950
|
+
@mouseClickedBlock__ = block if block
|
2951
|
+
nil
|
2515
2952
|
end
|
2516
2953
|
|
2517
|
-
#
|
2518
|
-
#
|
2519
|
-
# @param value [Numeric] number to be mapped
|
2520
|
-
# @param start1 [Numeric] lower bound of the range1
|
2521
|
-
# @param stop1 [Numeric] upper bound of the range1
|
2522
|
-
# @param start2 [Numeric] lower bound of the range2
|
2523
|
-
# @param stop2 [Numeric] upper bound of the range2
|
2954
|
+
# Defines touchStarted block.
|
2524
2955
|
#
|
2525
|
-
# @return [
|
2956
|
+
# @return [nil] nil
|
2526
2957
|
#
|
2527
|
-
def
|
2528
|
-
|
2958
|
+
def touchStarted(&block)
|
2959
|
+
@touchStartedBlock__ = block if block
|
2960
|
+
nil
|
2529
2961
|
end
|
2530
2962
|
|
2531
|
-
#
|
2532
|
-
#
|
2533
|
-
# @overload min(a, b)
|
2534
|
-
# @overload min(a, b, c)
|
2535
|
-
# @overload min(array)
|
2536
|
-
#
|
2537
|
-
# @param a [Numeric] value to compare
|
2538
|
-
# @param b [Numeric] value to compare
|
2539
|
-
# @param c [Numeric] value to compare
|
2540
|
-
# @param array [Numeric] values to compare
|
2963
|
+
# Defines touchEnded block.
|
2541
2964
|
#
|
2542
|
-
# @return [
|
2965
|
+
# @return [nil] nil
|
2543
2966
|
#
|
2544
|
-
def
|
2545
|
-
|
2967
|
+
def touchEnded(&block)
|
2968
|
+
@touchEndedBlock__ = block if block
|
2969
|
+
nil
|
2546
2970
|
end
|
2547
2971
|
|
2548
|
-
#
|
2972
|
+
# Defines touchMoved block.
|
2549
2973
|
#
|
2550
|
-
# @
|
2551
|
-
# @overload max(a, b, c)
|
2552
|
-
# @overload max(array)
|
2974
|
+
# @return [nil] nil
|
2553
2975
|
#
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2976
|
+
def touchMoved(&block)
|
2977
|
+
@touchMovedBlock__ = block if block
|
2978
|
+
nil
|
2979
|
+
end
|
2980
|
+
|
2981
|
+
# Defines motion block.
|
2558
2982
|
#
|
2559
|
-
# @return [
|
2983
|
+
# @return [nil] nil
|
2560
2984
|
#
|
2561
|
-
def
|
2562
|
-
|
2985
|
+
def motion(&block)
|
2986
|
+
@motionBlock__ = block if block
|
2987
|
+
nil
|
2563
2988
|
end
|
2564
2989
|
|
2565
|
-
#
|
2990
|
+
# Changes canvas size.
|
2566
2991
|
#
|
2567
|
-
# @param
|
2568
|
-
# @param
|
2569
|
-
# @param
|
2992
|
+
# @param width [Integer] new width
|
2993
|
+
# @param height [Integer] new height
|
2994
|
+
# @param pixelDensity [Numeric] new pixel density
|
2570
2995
|
#
|
2571
|
-
# @return [
|
2996
|
+
# @return [nil] nil
|
2572
2997
|
#
|
2573
|
-
def
|
2574
|
-
|
2998
|
+
def size(width, height, pixelDensity: self.pixelDensity)
|
2999
|
+
resizeCanvas__ :size, width, height, pixelDensity
|
3000
|
+
nil
|
2575
3001
|
end
|
2576
3002
|
|
2577
|
-
#
|
3003
|
+
# Changes canvas size.
|
2578
3004
|
#
|
2579
|
-
# @param
|
3005
|
+
# @param width [Integer] new width
|
3006
|
+
# @param height [Integer] new height
|
3007
|
+
# @param pixelDensity [Numeric] new pixel density
|
2580
3008
|
#
|
2581
|
-
# @return [
|
3009
|
+
# @return [nil] nil
|
2582
3010
|
#
|
2583
|
-
def
|
2584
|
-
|
3011
|
+
def createCanvas(width, height, pixelDensity: self.pixelDensity)
|
3012
|
+
resizeCanvas__ :createCanvas, width, height, pixelDensity
|
3013
|
+
nil
|
2585
3014
|
end
|
2586
3015
|
|
2587
|
-
#
|
3016
|
+
# Changes title of window.
|
2588
3017
|
#
|
2589
|
-
# @param
|
3018
|
+
# @param title [String] new title
|
2590
3019
|
#
|
2591
|
-
# @return [
|
3020
|
+
# @return [nil] nil
|
2592
3021
|
#
|
2593
|
-
def
|
2594
|
-
|
3022
|
+
def setTitle(title)
|
3023
|
+
@window__.title = title
|
3024
|
+
nil
|
2595
3025
|
end
|
2596
3026
|
|
2597
|
-
#
|
3027
|
+
# Changes and returns canvas pixel density.
|
2598
3028
|
#
|
2599
|
-
# @param
|
3029
|
+
# @param density [Numeric] new pixel density
|
2600
3030
|
#
|
2601
|
-
# @return [Numeric]
|
3031
|
+
# @return [Numeric] current pixel density
|
2602
3032
|
#
|
2603
|
-
def
|
2604
|
-
|
3033
|
+
def pixelDensity(density = nil)
|
3034
|
+
resizeCanvas__ :pixelDensity, width, height, density if density
|
3035
|
+
@painter__.pixel_density
|
2605
3036
|
end
|
2606
3037
|
|
2607
|
-
#
|
2608
|
-
|
2609
|
-
|
3038
|
+
# @private
|
3039
|
+
def resizeCanvas__(name, width, height, pixelDensity)
|
3040
|
+
raise '#{name}() must be called on startup or setup block' if @started__
|
3041
|
+
|
3042
|
+
@painter__.__send__ :end_paint
|
3043
|
+
@window__.resize_canvas width, height, pixelDensity
|
3044
|
+
@window__.auto_resize = false
|
3045
|
+
ensure
|
3046
|
+
@painter__.__send__ :begin_paint
|
3047
|
+
end
|
3048
|
+
|
3049
|
+
# Returns pixel density of display.
|
2610
3050
|
#
|
2611
|
-
# @return [Numeric]
|
3051
|
+
# @return [Numeric] pixel density
|
2612
3052
|
#
|
2613
|
-
def
|
2614
|
-
|
3053
|
+
def displayDensity()
|
3054
|
+
@window__.painter.pixel_density
|
2615
3055
|
end
|
2616
3056
|
|
2617
|
-
# Returns
|
2618
|
-
#
|
2619
|
-
# @param angle [Numeric] angle in radians
|
3057
|
+
# Returns window width.
|
2620
3058
|
#
|
2621
|
-
# @return [Numeric]
|
3059
|
+
# @return [Numeric] window width
|
2622
3060
|
#
|
2623
|
-
def
|
2624
|
-
|
3061
|
+
def windowWidth()
|
3062
|
+
@window__.width
|
2625
3063
|
end
|
2626
3064
|
|
2627
|
-
# Returns
|
2628
|
-
#
|
2629
|
-
# @param value [Numeric] value for calculation
|
3065
|
+
# Returns window height.
|
2630
3066
|
#
|
2631
|
-
# @return [Numeric]
|
3067
|
+
# @return [Numeric] window height
|
2632
3068
|
#
|
2633
|
-
def
|
2634
|
-
|
3069
|
+
def windowHeight()
|
3070
|
+
@window__.height
|
2635
3071
|
end
|
2636
3072
|
|
2637
|
-
# Returns
|
2638
|
-
#
|
2639
|
-
# @param value [Numeric] value for calculation
|
3073
|
+
# Returns number of frames since program started.
|
2640
3074
|
#
|
2641
|
-
# @return [
|
3075
|
+
# @return [Integer] total number of frames
|
2642
3076
|
#
|
2643
|
-
def
|
2644
|
-
|
3077
|
+
def frameCount()
|
3078
|
+
@frameCount__
|
2645
3079
|
end
|
2646
3080
|
|
2647
|
-
# Returns
|
2648
|
-
#
|
2649
|
-
# @param value [Numeric] value for valculation
|
3081
|
+
# Returns number of frames per second.
|
2650
3082
|
#
|
2651
|
-
# @return [
|
3083
|
+
# @return [Float] frames per second
|
2652
3084
|
#
|
2653
|
-
def
|
2654
|
-
|
3085
|
+
def frameRate()
|
3086
|
+
@window__.event.fps
|
2655
3087
|
end
|
2656
3088
|
|
2657
|
-
# Returns the
|
2658
|
-
#
|
2659
|
-
# @param y [Numeric] y of the point
|
2660
|
-
# @param x [Numeric] x of the point
|
3089
|
+
# Returns the last key that was pressed or released.
|
2661
3090
|
#
|
2662
|
-
# @return [
|
3091
|
+
# @return [String] last key
|
2663
3092
|
#
|
2664
|
-
def
|
2665
|
-
|
3093
|
+
def key()
|
3094
|
+
@key__
|
2666
3095
|
end
|
2667
3096
|
|
2668
|
-
# Returns the
|
3097
|
+
# Returns the last key code that was pressed or released.
|
2669
3098
|
#
|
2670
|
-
# @
|
2671
|
-
# @overload noise(x, y)
|
2672
|
-
# @overload noise(x, y, z)
|
3099
|
+
# @return [Symbol] last key code
|
2673
3100
|
#
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
3101
|
+
def keyCode()
|
3102
|
+
@keyCode__
|
3103
|
+
end
|
3104
|
+
|
3105
|
+
# Returns mouse x position
|
2677
3106
|
#
|
2678
|
-
# @return [Numeric]
|
3107
|
+
# @return [Numeric] horizontal position of mouse
|
2679
3108
|
#
|
2680
|
-
def
|
2681
|
-
|
3109
|
+
def mouseX()
|
3110
|
+
@pointerPos__.x
|
2682
3111
|
end
|
2683
3112
|
|
2684
|
-
# Returns
|
3113
|
+
# Returns mouse y position
|
2685
3114
|
#
|
2686
|
-
# @
|
2687
|
-
# @overload random(high)
|
2688
|
-
# @overload random(low, high)
|
2689
|
-
# @overload random(choices)
|
3115
|
+
# @return [Numeric] vertical position of mouse
|
2690
3116
|
#
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
3117
|
+
def mouseY()
|
3118
|
+
@pointerPos__.y
|
3119
|
+
end
|
3120
|
+
|
3121
|
+
# Returns mouse x position in previous frame
|
2694
3122
|
#
|
2695
|
-
# @return [
|
3123
|
+
# @return [Numeric] horizontal position of mouse
|
2696
3124
|
#
|
2697
|
-
def
|
2698
|
-
|
2699
|
-
high, low = args.reverse
|
2700
|
-
rand (low || 0).to_f...(high || 1).to_f
|
3125
|
+
def pmouseX()
|
3126
|
+
@pointerPrevPos__.x
|
2701
3127
|
end
|
2702
3128
|
|
2703
|
-
#
|
3129
|
+
# Returns mouse y position in previous frame
|
2704
3130
|
#
|
2705
|
-
# @
|
2706
|
-
# @overload createVector(x, y)
|
2707
|
-
# @overload createVector(x, y, z)
|
3131
|
+
# @return [Numeric] vertical position of mouse
|
2708
3132
|
#
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
3133
|
+
def pmouseY()
|
3134
|
+
@pointerPrevPos__.y
|
3135
|
+
end
|
3136
|
+
|
3137
|
+
# Returns which mouse button was pressed
|
2712
3138
|
#
|
2713
|
-
# @return [
|
3139
|
+
# @return [Numeric] LEFT, RIGHT, CENTER or 0
|
2714
3140
|
#
|
2715
|
-
def
|
2716
|
-
|
3141
|
+
def mouseButton()
|
3142
|
+
(@pointersPressed__ & [LEFT, RIGHT, CENTER]).last || 0
|
2717
3143
|
end
|
2718
3144
|
|
2719
|
-
#
|
3145
|
+
# Returns array of touches
|
2720
3146
|
#
|
2721
|
-
# @return [
|
3147
|
+
# @return [Array] Touch objects
|
2722
3148
|
#
|
2723
|
-
def
|
2724
|
-
|
3149
|
+
def touches()
|
3150
|
+
@touches__
|
2725
3151
|
end
|
2726
3152
|
|
2727
|
-
#
|
2728
|
-
#
|
2729
|
-
# @param width [Numeric] width of graphics image
|
2730
|
-
# @param height [Numeric] height of graphics image
|
3153
|
+
# Returns vector for real world gravity
|
2731
3154
|
#
|
2732
|
-
# @return [
|
3155
|
+
# @return [Vector] gravity vector
|
2733
3156
|
#
|
2734
|
-
def
|
2735
|
-
|
3157
|
+
def motionGravity()
|
3158
|
+
@motionGravity__
|
2736
3159
|
end
|
2737
3160
|
|
2738
|
-
#
|
2739
|
-
#
|
2740
|
-
# @param filename [String] file name to load image
|
2741
|
-
# @param extension [String] type of image to load (ex. 'png')
|
3161
|
+
# Enables calling draw block on every frame.
|
2742
3162
|
#
|
2743
|
-
# @return [
|
3163
|
+
# @return [nil] nil
|
2744
3164
|
#
|
2745
|
-
def
|
2746
|
-
|
2747
|
-
Image.new Rays::Image.load filename
|
3165
|
+
def loop()
|
3166
|
+
@loop__ = true
|
2748
3167
|
end
|
2749
3168
|
|
2750
|
-
#
|
2751
|
-
|
2752
|
-
|
2753
|
-
|
2754
|
-
|
2755
|
-
|
2756
|
-
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2757
|
-
path = path.sub_ext ext
|
2758
|
-
|
2759
|
-
unless path.file?
|
2760
|
-
URI.open uri do |input|
|
2761
|
-
input.set_encoding nil# disable default_internal
|
2762
|
-
tmpdir.mkdir unless tmpdir.directory?
|
2763
|
-
path.open('w') do |output|
|
2764
|
-
output.set_encoding Encoding::ASCII_8BIT
|
2765
|
-
while buf = input.read(2 ** 16)
|
2766
|
-
output.write buf
|
2767
|
-
end
|
2768
|
-
end
|
2769
|
-
end
|
2770
|
-
end
|
2771
|
-
path.to_s
|
3169
|
+
# Disables calling draw block on every frame.
|
3170
|
+
#
|
3171
|
+
# @return [nil] nil
|
3172
|
+
#
|
3173
|
+
def noLoop()
|
3174
|
+
@loop__ = false
|
2772
3175
|
end
|
2773
3176
|
|
2774
|
-
#
|
2775
|
-
|
2776
|
-
|
3177
|
+
# Calls draw block to redraw frame.
|
3178
|
+
#
|
3179
|
+
# @return [nil] nil
|
3180
|
+
#
|
3181
|
+
def redraw()
|
3182
|
+
@redraw__ = true
|
2777
3183
|
end
|
2778
3184
|
|
2779
3185
|
end# Context
|