rubysketch 0.3.21 → 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/ChangeLog.md +15 -1
- data/VERSION +1 -1
- data/lib/rubysketch/glsl.rb +10 -4
- data/lib/rubysketch/processing.rb +983 -702
- data/lib/rubysketch/window.rb +91 -64
- data/lib/rubysketch-glsl.rb +2 -1
- data/rubysketch.gemspec +1 -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 +10 -4
@@ -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
|
@@ -633,14 +647,14 @@ module RubySketch
|
|
633
647
|
# @overload blend(img, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
634
648
|
#
|
635
649
|
# @param img [Image] image for blend source
|
636
|
-
# @param sx [
|
637
|
-
# @param sy [
|
638
|
-
# @param sw [
|
639
|
-
# @param sh [
|
640
|
-
# @param dx [
|
641
|
-
# @param dy [
|
642
|
-
# @param dw [
|
643
|
-
# @param dh [
|
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
|
644
658
|
# @param mode [BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, EXCLUSION, MULTIPLY, SCREEN, REPLACE] blend mode
|
645
659
|
#
|
646
660
|
# @return [nil] nil
|
@@ -648,11 +662,9 @@ module RubySketch
|
|
648
662
|
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
649
663
|
img ||= self
|
650
664
|
@image.paint do |painter|
|
651
|
-
|
652
|
-
painter.blend_mode = mode
|
653
|
-
painter.image img.getInternal__, sx, sy, sw, sh, dx, dy, dw, dh
|
654
|
-
painter.blend_mode = current
|
665
|
+
img.drawImage__ painter, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
655
666
|
end
|
667
|
+
nil
|
656
668
|
end
|
657
669
|
|
658
670
|
# Saves image to file.
|
@@ -668,6 +680,14 @@ module RubySketch
|
|
668
680
|
@image
|
669
681
|
end
|
670
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
|
+
|
671
691
|
end# Image
|
672
692
|
|
673
693
|
|
@@ -753,6 +773,159 @@ module RubySketch
|
|
753
773
|
end# Touch
|
754
774
|
|
755
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
|
+
|
756
929
|
# Camera object.
|
757
930
|
#
|
758
931
|
class Capture
|
@@ -838,14 +1011,31 @@ module RubySketch
|
|
838
1011
|
@camera.image&.height || 0
|
839
1012
|
end
|
840
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
|
+
|
841
1028
|
# @private
|
842
1029
|
def getInternal__()
|
843
|
-
@camera.image ||
|
1030
|
+
@camera.image || (@dummyImage ||= Rays::Image.new 1, 1)
|
844
1031
|
end
|
845
1032
|
|
846
1033
|
# @private
|
847
|
-
|
848
|
-
|
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
|
849
1039
|
end
|
850
1040
|
|
851
1041
|
end# Capture
|
@@ -978,6 +1168,18 @@ module RubySketch
|
|
978
1168
|
# Mode for textAlign().
|
979
1169
|
BASELINE = :baseline
|
980
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
|
+
|
981
1183
|
# Key codes.
|
982
1184
|
ENTER = :enter
|
983
1185
|
SPACE = :space
|
@@ -1036,9 +1238,10 @@ module RubySketch
|
|
1036
1238
|
@rectMode__ = nil
|
1037
1239
|
@ellipseMode__ = nil
|
1038
1240
|
@imageMode__ = nil
|
1039
|
-
@tint__ = nil
|
1040
1241
|
@textAlignH__ = nil
|
1041
1242
|
@textAlignV__ = nil
|
1243
|
+
@tint__ = nil
|
1244
|
+
@filter__ = nil
|
1042
1245
|
@matrixStack__ = []
|
1043
1246
|
@styleStack__ = []
|
1044
1247
|
@fontCache__ = {}
|
@@ -1068,6 +1271,7 @@ module RubySketch
|
|
1068
1271
|
|
1069
1272
|
# @private
|
1070
1273
|
def beginDraw__()
|
1274
|
+
raise "call beginDraw() before drawing" if @drawing__
|
1071
1275
|
@matrixStack__.clear
|
1072
1276
|
@styleStack__.clear
|
1073
1277
|
@drawing__ = true
|
@@ -1075,6 +1279,7 @@ module RubySketch
|
|
1075
1279
|
|
1076
1280
|
# @private
|
1077
1281
|
def endDraw__()
|
1282
|
+
raise unless @drawing__
|
1078
1283
|
@drawing__ = false
|
1079
1284
|
end
|
1080
1285
|
|
@@ -1442,6 +1647,40 @@ module RubySketch
|
|
1442
1647
|
@painter__.font = font
|
1443
1648
|
end
|
1444
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
|
+
|
1445
1684
|
# Clears screen.
|
1446
1685
|
#
|
1447
1686
|
# @overload background(str)
|
@@ -1727,12 +1966,9 @@ module RubySketch
|
|
1727
1966
|
#
|
1728
1967
|
def image(img, a, b, c = nil, d = nil)
|
1729
1968
|
assertDrawing__
|
1730
|
-
|
1731
|
-
x, y, w, h = toXYWH__ @imageMode__, a, b, c || i.width, d || i.height
|
1969
|
+
x, y, w, h = toXYWH__ @imageMode__, a, b, c || img.width, d || img.height
|
1732
1970
|
tint = @tint__ ? toRGBA__(*@tint__) : 1
|
1733
|
-
@painter__
|
1734
|
-
@painter__.image i, x, y, w, h
|
1735
|
-
end
|
1971
|
+
img.drawImage__ @painter__, x, y, w, h, fill: tint, stroke: :none
|
1736
1972
|
nil
|
1737
1973
|
end
|
1738
1974
|
|
@@ -1777,12 +2013,8 @@ module RubySketch
|
|
1777
2013
|
#
|
1778
2014
|
def blend(img = nil, sx, sy, sw, sh, dx, dy, dw, dh, mode)
|
1779
2015
|
assertDrawing__
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
@painter__.blend_mode = mode
|
1784
|
-
@painter__.image src, sx, sy, sw, sh, dx, dy, dw, dh
|
1785
|
-
@painter__.blend_mode = current
|
2016
|
+
img ||= self
|
2017
|
+
img.drawImage__ @painter__, sx, sy, sw, sh, dx, dy, dw, dh, blend_mode: mode
|
1786
2018
|
end
|
1787
2019
|
|
1788
2020
|
# Saves screen image to file.
|
@@ -1846,11 +2078,10 @@ module RubySketch
|
|
1846
2078
|
def pushMatrix(&block)
|
1847
2079
|
assertDrawing__
|
1848
2080
|
@matrixStack__.push @painter__.matrix
|
1849
|
-
if block
|
1850
|
-
block.call
|
1851
|
-
popMatrix
|
1852
|
-
end
|
2081
|
+
block.call if block
|
1853
2082
|
nil
|
2083
|
+
ensure
|
2084
|
+
popMatrix if block
|
1854
2085
|
end
|
1855
2086
|
|
1856
2087
|
# Pops the current transformation matrix from stack.
|
@@ -1889,18 +2120,22 @@ module RubySketch
|
|
1889
2120
|
@painter__.clip,
|
1890
2121
|
@painter__.blend_mode,
|
1891
2122
|
@painter__.font,
|
2123
|
+
@painter__.shader,
|
1892
2124
|
@hsbColor__,
|
1893
2125
|
@colorMaxes__,
|
1894
2126
|
@angleScale__,
|
1895
2127
|
@rectMode__,
|
1896
2128
|
@ellipseMode__,
|
1897
|
-
@imageMode__
|
2129
|
+
@imageMode__,
|
2130
|
+
@textAlignH__,
|
2131
|
+
@textAlignV__,
|
2132
|
+
@tint__,
|
2133
|
+
@filter__,
|
1898
2134
|
]
|
1899
|
-
if block
|
1900
|
-
block.call
|
1901
|
-
popStyle
|
1902
|
-
end
|
2135
|
+
block.call if block
|
1903
2136
|
nil
|
2137
|
+
ensure
|
2138
|
+
popStyle if block
|
1904
2139
|
end
|
1905
2140
|
|
1906
2141
|
# Restore style values from the style stack.
|
@@ -1918,12 +2153,17 @@ module RubySketch
|
|
1918
2153
|
@painter__.clip,
|
1919
2154
|
@painter__.blend_mode,
|
1920
2155
|
@painter__.font,
|
2156
|
+
@painter__.shader,
|
1921
2157
|
@hsbColor__,
|
1922
2158
|
@colorMaxes__,
|
1923
2159
|
@angleScale__,
|
1924
2160
|
@rectMode__,
|
1925
2161
|
@ellipseMode__,
|
1926
|
-
@imageMode__
|
2162
|
+
@imageMode__,
|
2163
|
+
@textAlignH__,
|
2164
|
+
@textAlignV__,
|
2165
|
+
@tint__,
|
2166
|
+
@filter__ = @styleStack__.pop
|
1927
2167
|
nil
|
1928
2168
|
end
|
1929
2169
|
|
@@ -1934,10 +2174,9 @@ module RubySketch
|
|
1934
2174
|
def push(&block)
|
1935
2175
|
pushMatrix
|
1936
2176
|
pushStyle
|
1937
|
-
if block
|
1938
|
-
|
1939
|
-
|
1940
|
-
end
|
2177
|
+
block.call if block
|
2178
|
+
ensure
|
2179
|
+
pop if block
|
1941
2180
|
end
|
1942
2181
|
|
1943
2182
|
# Restore styles and transformations from stack.
|
@@ -1954,951 +2193,993 @@ module RubySketch
|
|
1954
2193
|
@image__
|
1955
2194
|
end
|
1956
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
|
+
|
1957
2204
|
# @private
|
1958
2205
|
private def assertDrawing__()
|
1959
2206
|
raise "call beginDraw() before drawing" unless @drawing__
|
1960
2207
|
end
|
1961
2208
|
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
# Draws graphics into an offscreen buffer
|
1966
|
-
#
|
1967
|
-
class Graphics
|
1968
|
-
|
1969
|
-
include GraphicsContext
|
2209
|
+
#
|
2210
|
+
# Utilities
|
2211
|
+
#
|
1970
2212
|
|
1971
|
-
#
|
2213
|
+
# Returns the absolute number of the value.
|
1972
2214
|
#
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
2215
|
+
# @param value [Numeric] number
|
2216
|
+
#
|
2217
|
+
# @return [Numeric] absolute number
|
2218
|
+
#
|
2219
|
+
def abs(value)
|
2220
|
+
value.abs
|
1976
2221
|
end
|
1977
2222
|
|
1978
|
-
#
|
2223
|
+
# Returns the closest integer number greater than or equal to the value.
|
1979
2224
|
#
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
endDraw
|
1987
|
-
end
|
2225
|
+
# @param value [Numeric] number
|
2226
|
+
#
|
2227
|
+
# @return [Numeric] rounded up number
|
2228
|
+
#
|
2229
|
+
def ceil(value)
|
2230
|
+
value.ceil
|
1988
2231
|
end
|
1989
2232
|
|
1990
|
-
#
|
2233
|
+
# Returns the closest integer number less than or equal to the value.
|
1991
2234
|
#
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
2235
|
+
# @param value [Numeric] number
|
2236
|
+
#
|
2237
|
+
# @return [Numeric] rounded down number
|
2238
|
+
#
|
2239
|
+
def floor(value)
|
2240
|
+
value.floor
|
1996
2241
|
end
|
1997
2242
|
|
1998
|
-
|
1999
|
-
|
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
|
2000
2252
|
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
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
|
2004
2262
|
|
2005
|
-
|
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
|
2006
2272
|
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
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
|
2010
2283
|
|
2011
|
-
#
|
2012
|
-
|
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
|
2013
2293
|
|
2014
|
-
#
|
2015
|
-
|
2016
|
-
|
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
|
2017
2302
|
end
|
2018
2303
|
|
2019
|
-
#
|
2020
|
-
|
2021
|
-
|
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
|
2321
|
+
end
|
2322
|
+
end
|
2022
2323
|
|
2023
|
-
|
2324
|
+
# Returns distance between 2 points.
|
2325
|
+
#
|
2326
|
+
# @overload dist(x1, y1, x2, y2)
|
2327
|
+
# @overload dist(x1, y1, z1, x2, y2, z2)
|
2328
|
+
#
|
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
|
2350
|
+
end
|
2024
2351
|
|
2025
|
-
|
2026
|
-
init__(
|
2027
|
-
@window__.canvas_image,
|
2028
|
-
@window__.canvas_painter.paint {background 0.8})
|
2029
|
-
|
2030
|
-
@loop__ = true
|
2031
|
-
@redraw__ = false
|
2032
|
-
@frameCount__ = 0
|
2033
|
-
@key__ = nil
|
2034
|
-
@keyCode__ = nil
|
2035
|
-
@keysPressed__ = Set.new
|
2036
|
-
@pointerPos__ =
|
2037
|
-
@pointerPrevPos__ = Rays::Point.new 0
|
2038
|
-
@pointersPressed__ = []
|
2039
|
-
@touches__ = []
|
2040
|
-
@motionGravity__ = createVector 0, 0
|
2041
|
-
|
2042
|
-
@window__.before_draw = proc {beginDraw__}
|
2043
|
-
@window__.after_draw = proc {endDraw__}
|
2044
|
-
|
2045
|
-
drawFrame = -> {
|
2046
|
-
updateCanvas__ @window__.canvas_image, @window__.canvas_painter
|
2047
|
-
begin
|
2048
|
-
push
|
2049
|
-
@drawBlock__.call if @drawBlock__
|
2050
|
-
ensure
|
2051
|
-
pop
|
2052
|
-
@frameCount__ += 1
|
2053
|
-
end
|
2054
|
-
}
|
2055
|
-
|
2056
|
-
@window__.draw = proc do |e|
|
2057
|
-
if @loop__ || @redraw__
|
2058
|
-
@redraw__ = false
|
2059
|
-
drawFrame.call
|
2060
|
-
end
|
2061
|
-
end
|
2062
|
-
|
2063
|
-
updateKeyStates = -> event, pressed {
|
2064
|
-
@key__ = event.chars
|
2065
|
-
@keyCode__ = event.key
|
2066
|
-
if pressed != nil
|
2067
|
-
set, key = @keysPressed__, event.key
|
2068
|
-
pressed ? set.add(key) : set.delete(key)
|
2069
|
-
end
|
2070
|
-
}
|
2071
|
-
|
2072
|
-
mouseButtonMap = {
|
2073
|
-
mouse_left: LEFT,
|
2074
|
-
mouse_right: RIGHT,
|
2075
|
-
mouse_middle: CENTER
|
2076
|
-
}
|
2077
|
-
|
2078
|
-
updatePointerStates = -> event, pressed = nil {
|
2079
|
-
@pointerPrevPos__ = @pointerPos__
|
2080
|
-
@pointerPos__ = event.pos.dup
|
2081
|
-
@touches__ = event.pointers.map {|p| Touch.new(p.id, *p.pos.to_a)}
|
2082
|
-
if pressed != nil
|
2083
|
-
array = @pointersPressed__
|
2084
|
-
event.types
|
2085
|
-
.tap {|types| types.delete :mouse}
|
2086
|
-
.map {|type| mouseButtonMap[type] || type}
|
2087
|
-
.each {|type| pressed ? array.push(type) : array.delete(type)}
|
2088
|
-
end
|
2089
|
-
}
|
2090
|
-
|
2091
|
-
@window__.key_down = proc do |e|
|
2092
|
-
updateKeyStates.call e, true
|
2093
|
-
@keyPressedBlock__&.call
|
2094
|
-
@keyTypedBlock__&.call if @key__ && !@key__.empty?
|
2095
|
-
end
|
2096
|
-
|
2097
|
-
@window__.key_up = proc do |e|
|
2098
|
-
updateKeyStates.call e, false
|
2099
|
-
@keyReleasedBlock__&.call
|
2100
|
-
end
|
2101
|
-
|
2102
|
-
@window__.pointer_down = proc do |e|
|
2103
|
-
updatePointerStates.call e, true
|
2104
|
-
@pointerDownStartPos__ = @pointerPos__.dup
|
2105
|
-
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
2106
|
-
end
|
2107
|
-
|
2108
|
-
@window__.pointer_up = proc do |e|
|
2109
|
-
updatePointerStates.call e, false
|
2110
|
-
(@touchEndedBlock__ || @mouseReleasedBlock__)&.call
|
2111
|
-
if startPos = @pointerDownStartPos__
|
2112
|
-
@mouseClickedBlock__&.call if (@pointerPos__ - startPos).length < 3
|
2113
|
-
@pointerDownStartPos__ = nil
|
2114
|
-
end
|
2115
|
-
end
|
2116
|
-
|
2117
|
-
@window__.pointer_move = proc do |e|
|
2118
|
-
updatePointerStates.call e
|
2119
|
-
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
2120
|
-
end
|
2121
|
-
|
2122
|
-
@window__.pointer_drag = proc do |e|
|
2123
|
-
updatePointerStates.call e
|
2124
|
-
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
2125
|
-
end
|
2126
|
-
|
2127
|
-
@window__.motion = proc do |e|
|
2128
|
-
@motionGravity__ = createVector(*e.gravity.to_a(3))
|
2129
|
-
@motionBlock__&.call
|
2130
|
-
end
|
2131
|
-
end
|
2132
|
-
|
2133
|
-
# Defines setup block.
|
2352
|
+
# Normalize the value from range start..stop into 0..1.
|
2134
2353
|
#
|
2135
|
-
# @
|
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
|
2136
2357
|
#
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
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)
|
2140
2362
|
end
|
2141
2363
|
|
2142
|
-
#
|
2364
|
+
# Returns the interpolated number between range start..stop.
|
2143
2365
|
#
|
2144
|
-
# @
|
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
|
2145
2369
|
#
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2370
|
+
# @return [Numeric] interporated number
|
2371
|
+
#
|
2372
|
+
def lerp(start, stop, amount)
|
2373
|
+
start + (stop - start) * amount
|
2149
2374
|
end
|
2150
2375
|
|
2151
|
-
#
|
2376
|
+
# Maps a number from range start1..stop1 to range start2..stop2.
|
2152
2377
|
#
|
2153
|
-
# @
|
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
|
2154
2383
|
#
|
2155
|
-
|
2156
|
-
|
2157
|
-
|
2384
|
+
# @return [Numeric] mapped number
|
2385
|
+
#
|
2386
|
+
def map(value, start1, stop1, start2, stop2)
|
2387
|
+
lerp start2, stop2, norm(value, start1, stop1)
|
2158
2388
|
end
|
2159
2389
|
|
2160
|
-
#
|
2390
|
+
# Returns minimum value.
|
2161
2391
|
#
|
2162
|
-
# @
|
2392
|
+
# @overload min(a, b)
|
2393
|
+
# @overload min(a, b, c)
|
2394
|
+
# @overload min(array)
|
2163
2395
|
#
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2167
|
-
|
2168
|
-
|
2169
|
-
# Defines keyTyped block.
|
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
|
2170
2400
|
#
|
2171
|
-
# @return [
|
2401
|
+
# @return [Numeric] minimum value
|
2172
2402
|
#
|
2173
|
-
def
|
2174
|
-
|
2175
|
-
nil
|
2403
|
+
def min(*args)
|
2404
|
+
args.flatten.min
|
2176
2405
|
end
|
2177
2406
|
|
2178
|
-
#
|
2407
|
+
# Returns maximum value.
|
2179
2408
|
#
|
2180
|
-
# @
|
2409
|
+
# @overload max(a, b)
|
2410
|
+
# @overload max(a, b, c)
|
2411
|
+
# @overload max(array)
|
2181
2412
|
#
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
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
|
2185
2422
|
end
|
2186
2423
|
|
2187
|
-
#
|
2424
|
+
# Constrains the number between min..max.
|
2188
2425
|
#
|
2189
|
-
# @
|
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
|
2190
2429
|
#
|
2191
|
-
|
2192
|
-
|
2193
|
-
|
2430
|
+
# @return [Numeric] constrained number
|
2431
|
+
#
|
2432
|
+
def constrain(value, min, max)
|
2433
|
+
value < min ? min : (value > max ? max : value)
|
2194
2434
|
end
|
2195
2435
|
|
2196
|
-
#
|
2436
|
+
# Converts degree to radian.
|
2197
2437
|
#
|
2198
|
-
# @
|
2438
|
+
# @param degree [Numeric] degree to convert
|
2199
2439
|
#
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2440
|
+
# @return [Numeric] radian
|
2441
|
+
#
|
2442
|
+
def radians(degree)
|
2443
|
+
degree * DEG2RAD__
|
2203
2444
|
end
|
2204
2445
|
|
2205
|
-
#
|
2446
|
+
# Converts radian to degree.
|
2206
2447
|
#
|
2207
|
-
# @
|
2448
|
+
# @param radian [Numeric] radian to convert
|
2208
2449
|
#
|
2209
|
-
|
2210
|
-
|
2211
|
-
|
2450
|
+
# @return [Numeric] degree
|
2451
|
+
#
|
2452
|
+
def degrees(radian)
|
2453
|
+
radian * RAD2DEG__
|
2212
2454
|
end
|
2213
2455
|
|
2214
|
-
#
|
2456
|
+
# Returns the sine of an angle.
|
2215
2457
|
#
|
2216
|
-
# @
|
2458
|
+
# @param angle [Numeric] angle in radians
|
2217
2459
|
#
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2460
|
+
# @return [Numeric] the sine
|
2461
|
+
#
|
2462
|
+
def sin(angle)
|
2463
|
+
Math.sin angle
|
2221
2464
|
end
|
2222
2465
|
|
2223
|
-
#
|
2466
|
+
# Returns the cosine of an angle.
|
2224
2467
|
#
|
2225
|
-
# @
|
2468
|
+
# @param angle [Numeric] angle in radians
|
2226
2469
|
#
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2470
|
+
# @return [Numeric] the cosine
|
2471
|
+
#
|
2472
|
+
def cos(angle)
|
2473
|
+
Math.cos angle
|
2230
2474
|
end
|
2231
2475
|
|
2232
|
-
#
|
2476
|
+
# Returns the ratio of the sine and cosine of an angle.
|
2233
2477
|
#
|
2234
|
-
# @
|
2478
|
+
# @param angle [Numeric] angle in radians
|
2235
2479
|
#
|
2236
|
-
|
2237
|
-
|
2238
|
-
|
2480
|
+
# @return [Numeric] the tangent
|
2481
|
+
#
|
2482
|
+
def tan(angle)
|
2483
|
+
Math.tan angle
|
2239
2484
|
end
|
2240
2485
|
|
2241
|
-
#
|
2486
|
+
# Returns the inverse of sin().
|
2242
2487
|
#
|
2243
|
-
# @
|
2488
|
+
# @param value [Numeric] value for calculation
|
2244
2489
|
#
|
2245
|
-
|
2246
|
-
|
2247
|
-
|
2490
|
+
# @return [Numeric] the arc sine
|
2491
|
+
#
|
2492
|
+
def asin(value)
|
2493
|
+
Math.asin value
|
2248
2494
|
end
|
2249
2495
|
|
2250
|
-
#
|
2496
|
+
# Returns the inverse of cos().
|
2251
2497
|
#
|
2252
|
-
# @
|
2498
|
+
# @param value [Numeric] value for calculation
|
2253
2499
|
#
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2500
|
+
# @return [Numeric] the arc cosine
|
2501
|
+
#
|
2502
|
+
def acos(value)
|
2503
|
+
Math.acos value
|
2257
2504
|
end
|
2258
2505
|
|
2259
|
-
#
|
2506
|
+
# Returns the inverse of tan().
|
2260
2507
|
#
|
2261
|
-
# @param
|
2262
|
-
# @param height [Integer] new height
|
2263
|
-
# @param pixelDensity [Numeric] new pixel density
|
2508
|
+
# @param value [Numeric] value for valculation
|
2264
2509
|
#
|
2265
|
-
# @return [
|
2510
|
+
# @return [Numeric] the arc tangent
|
2266
2511
|
#
|
2267
|
-
def
|
2268
|
-
|
2269
|
-
nil
|
2512
|
+
def atan(value)
|
2513
|
+
Math.atan value
|
2270
2514
|
end
|
2271
2515
|
|
2272
|
-
#
|
2516
|
+
# Returns the angle from a specified point.
|
2273
2517
|
#
|
2274
|
-
# @param
|
2275
|
-
# @param
|
2276
|
-
# @param pixelDensity [Numeric] new pixel density
|
2518
|
+
# @param y [Numeric] y of the point
|
2519
|
+
# @param x [Numeric] x of the point
|
2277
2520
|
#
|
2278
|
-
# @return [
|
2521
|
+
# @return [Numeric] the angle in radians
|
2279
2522
|
#
|
2280
|
-
def
|
2281
|
-
|
2282
|
-
nil
|
2523
|
+
def atan2(y, x)
|
2524
|
+
Math.atan2 y, x
|
2283
2525
|
end
|
2284
2526
|
|
2285
|
-
#
|
2527
|
+
# Returns the perlin noise value.
|
2286
2528
|
#
|
2287
|
-
# @
|
2529
|
+
# @overload noise(x)
|
2530
|
+
# @overload noise(x, y)
|
2531
|
+
# @overload noise(x, y, z)
|
2288
2532
|
#
|
2289
|
-
# @
|
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
|
2290
2536
|
#
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
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
|
2294
2541
|
end
|
2295
2542
|
|
2296
|
-
#
|
2543
|
+
# Returns a random number in range low...high
|
2297
2544
|
#
|
2298
|
-
# @
|
2545
|
+
# @overload random()
|
2546
|
+
# @overload random(high)
|
2547
|
+
# @overload random(low, high)
|
2548
|
+
# @overload random(choices)
|
2299
2549
|
#
|
2300
|
-
# @
|
2550
|
+
# @param low [Numeric] lower limit
|
2551
|
+
# @param high [Numeric] upper limit
|
2552
|
+
# @param choices [Array] array to choose from
|
2301
2553
|
#
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
def resizeCanvas__(name, width, height, pixelDensity)
|
2309
|
-
raise '#{name}() must be called on startup or setup block' if @started__
|
2310
|
-
|
2311
|
-
@painter__.__send__ :end_paint
|
2312
|
-
begin
|
2313
|
-
@window__.__send__ :resize_canvas, width, height, pixelDensity
|
2314
|
-
updateCanvas__ @window__.canvas_image, @window__.canvas_painter
|
2315
|
-
ensure
|
2316
|
-
@painter__.__send__ :begin_paint
|
2317
|
-
end
|
2318
|
-
|
2319
|
-
@window__.auto_resize = false
|
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
|
2320
2560
|
end
|
2321
2561
|
|
2322
|
-
#
|
2562
|
+
# Creates a new vector.
|
2323
2563
|
#
|
2324
|
-
# @
|
2564
|
+
# @overload createVector()
|
2565
|
+
# @overload createVector(x, y)
|
2566
|
+
# @overload createVector(x, y, z)
|
2325
2567
|
#
|
2326
|
-
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
# 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
|
2331
2571
|
#
|
2332
|
-
# @return [
|
2572
|
+
# @return [Vector] new vector
|
2333
2573
|
#
|
2334
|
-
def
|
2335
|
-
|
2574
|
+
def createVector(*args)
|
2575
|
+
Vector.new(*args, context: self)
|
2336
2576
|
end
|
2337
2577
|
|
2338
|
-
#
|
2578
|
+
# Creates a new image.
|
2339
2579
|
#
|
2340
|
-
# @
|
2580
|
+
# @overload createImage(w, h)
|
2581
|
+
# @overload createImage(w, h, format)
|
2341
2582
|
#
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
# 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
|
2347
2586
|
#
|
2348
|
-
# @return [
|
2587
|
+
# @return [Image] new image
|
2349
2588
|
#
|
2350
|
-
def
|
2351
|
-
|
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}
|
2352
2593
|
end
|
2353
2594
|
|
2354
|
-
#
|
2595
|
+
# Creates a new off-screen graphics context object.
|
2355
2596
|
#
|
2356
|
-
# @
|
2597
|
+
# @param width [Numeric] width of graphics image
|
2598
|
+
# @param height [Numeric] height of graphics image
|
2357
2599
|
#
|
2358
|
-
|
2359
|
-
|
2600
|
+
# @return [Graphics] graphics object
|
2601
|
+
#
|
2602
|
+
def createGraphics(width, height)
|
2603
|
+
Graphics.new width, height
|
2360
2604
|
end
|
2361
2605
|
|
2362
|
-
#
|
2606
|
+
# Creates a shader object.
|
2363
2607
|
#
|
2364
|
-
# @
|
2608
|
+
# @overload createShader(vertPath, fragPath)
|
2609
|
+
# @overload createShader(vertSource, fragSource)
|
2365
2610
|
#
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2369
|
-
|
2370
|
-
# 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
|
2371
2615
|
#
|
2372
|
-
# @return [
|
2616
|
+
# @return [Shader] shader object
|
2373
2617
|
#
|
2374
|
-
def
|
2375
|
-
|
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
|
2376
2622
|
end
|
2377
2623
|
|
2378
|
-
#
|
2624
|
+
# Creates a camera object as a video input device.
|
2379
2625
|
#
|
2380
|
-
# @return [
|
2626
|
+
# @return [Capture] camera object
|
2381
2627
|
#
|
2382
|
-
def
|
2383
|
-
|
2628
|
+
def createCapture(*args)
|
2629
|
+
Capture.new(*args)
|
2384
2630
|
end
|
2385
2631
|
|
2386
|
-
#
|
2632
|
+
# Loads image.
|
2387
2633
|
#
|
2388
|
-
# @
|
2634
|
+
# @param filename [String] file name to load image
|
2635
|
+
# @param extension [String] type of image to load (ex. 'png')
|
2389
2636
|
#
|
2390
|
-
|
2391
|
-
|
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
|
2392
2642
|
end
|
2393
2643
|
|
2394
|
-
#
|
2644
|
+
# Loads shader file.
|
2395
2645
|
#
|
2396
|
-
# @
|
2646
|
+
# @overload loadShader(fragPath)
|
2647
|
+
# @overload loadShader(fragPath, vertPath)
|
2397
2648
|
#
|
2398
|
-
|
2399
|
-
|
2400
|
-
end
|
2401
|
-
|
2402
|
-
# Returns mouse y position in previous frame
|
2649
|
+
# @param fragPath [String] fragment shader file path
|
2650
|
+
# @param vertPath [String] vertex shader file path
|
2403
2651
|
#
|
2404
|
-
# @return [
|
2652
|
+
# @return [Shader] loaded shader object
|
2405
2653
|
#
|
2406
|
-
def
|
2407
|
-
|
2654
|
+
def loadShader(fragPath, vertPath = nil)
|
2655
|
+
createShader vertPath, fragPath
|
2408
2656
|
end
|
2409
2657
|
|
2410
|
-
#
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
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
|
2416
2680
|
end
|
2417
2681
|
|
2418
|
-
#
|
2419
|
-
|
2420
|
-
|
2421
|
-
#
|
2422
|
-
def touches()
|
2423
|
-
@touches__
|
2682
|
+
# @private
|
2683
|
+
private def tmpdir__()
|
2684
|
+
Pathname(Dir.tmpdir) + Digest::SHA1.hexdigest(self.class.name)
|
2424
2685
|
end
|
2425
2686
|
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
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.
|
2429
2697
|
#
|
2430
|
-
def
|
2431
|
-
|
2698
|
+
def initialize(width, height)
|
2699
|
+
image = Rays::Image.new width, height
|
2700
|
+
init__ image, image.painter
|
2432
2701
|
end
|
2433
2702
|
|
2434
|
-
#
|
2435
|
-
#
|
2436
|
-
# @return [nil] nil
|
2703
|
+
# Start drawing.
|
2437
2704
|
#
|
2438
|
-
def
|
2439
|
-
|
2705
|
+
def beginDraw(&block)
|
2706
|
+
beginDraw__
|
2707
|
+
@painter__.__send__ :begin_paint
|
2708
|
+
push
|
2709
|
+
if block
|
2710
|
+
block.call
|
2711
|
+
endDraw
|
2712
|
+
end
|
2440
2713
|
end
|
2441
2714
|
|
2442
|
-
#
|
2443
|
-
#
|
2444
|
-
# @return [nil] nil
|
2715
|
+
# End drawing.
|
2445
2716
|
#
|
2446
|
-
def
|
2447
|
-
|
2717
|
+
def endDraw()
|
2718
|
+
pop
|
2719
|
+
@painter__.__send__ :end_paint
|
2720
|
+
endDraw__
|
2448
2721
|
end
|
2449
2722
|
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
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__
|
2456
2743
|
end
|
2457
2744
|
|
2458
|
-
#
|
2459
|
-
|
2460
|
-
|
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
|
2832
|
+
|
2833
|
+
@window__.pointer_down = proc do |e|
|
2834
|
+
updatePointerStates.call e, true
|
2835
|
+
@pointerDownStartPos__ = @pointerPos__.dup
|
2836
|
+
(@touchStartedBlock__ || @mousePressedBlock__)&.call
|
2837
|
+
end
|
2461
2838
|
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
|
2468
|
-
|
2469
|
-
|
2470
|
-
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
|
2471
2847
|
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
# @return [Numeric] rounded up number
|
2477
|
-
#
|
2478
|
-
def ceil(value)
|
2479
|
-
value.ceil
|
2480
|
-
end
|
2848
|
+
@window__.pointer_move = proc do |e|
|
2849
|
+
updatePointerStates.call e
|
2850
|
+
(@touchMovedBlock__ || @mouseMovedBlock__)&.call
|
2851
|
+
end
|
2481
2852
|
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
# @return [Numeric] rounded down number
|
2487
|
-
#
|
2488
|
-
def floor(value)
|
2489
|
-
value.floor
|
2490
|
-
end
|
2853
|
+
@window__.pointer_drag = proc do |e|
|
2854
|
+
updatePointerStates.call e
|
2855
|
+
(@touchMovedBlock__ || @mouseDraggedBlock__)&.call
|
2856
|
+
end
|
2491
2857
|
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
# @return [Numeric] rounded number
|
2497
|
-
#
|
2498
|
-
def round(value)
|
2499
|
-
value.round
|
2858
|
+
@window__.motion = proc do |e|
|
2859
|
+
@motionGravity__ = createVector(*e.gravity.to_a(3))
|
2860
|
+
@motionBlock__&.call
|
2861
|
+
end
|
2500
2862
|
end
|
2501
2863
|
|
2502
|
-
#
|
2503
|
-
#
|
2504
|
-
# @param value [Numeric] number (> 0.0)
|
2864
|
+
# Defines setup block.
|
2505
2865
|
#
|
2506
|
-
# @return [
|
2866
|
+
# @return [nil] nil
|
2507
2867
|
#
|
2508
|
-
def
|
2509
|
-
|
2868
|
+
def setup(&block)
|
2869
|
+
@window__.setup = block
|
2870
|
+
nil
|
2510
2871
|
end
|
2511
2872
|
|
2512
|
-
#
|
2513
|
-
#
|
2514
|
-
# @param value [Numeric] number
|
2873
|
+
# Defines draw block.
|
2515
2874
|
#
|
2516
|
-
# @return [
|
2875
|
+
# @return [nil] nil
|
2517
2876
|
#
|
2518
|
-
def
|
2519
|
-
|
2877
|
+
def draw(&block)
|
2878
|
+
@drawBlock__ = block if block
|
2879
|
+
nil
|
2520
2880
|
end
|
2521
2881
|
|
2522
|
-
#
|
2523
|
-
#
|
2524
|
-
# @param value [Numeric] base number
|
2525
|
-
# @param exponent [Numeric] exponent number
|
2882
|
+
# Defines keyPressed block.
|
2526
2883
|
#
|
2527
|
-
# @return [
|
2884
|
+
# @return [Boolean] is any key pressed or not
|
2528
2885
|
#
|
2529
|
-
def
|
2530
|
-
|
2886
|
+
def keyPressed(&block)
|
2887
|
+
@keyPressedBlock__ = block if block
|
2888
|
+
not @keysPressed__.empty?
|
2531
2889
|
end
|
2532
2890
|
|
2533
|
-
#
|
2534
|
-
#
|
2535
|
-
# @param value [Numeric] number
|
2891
|
+
# Defines keyReleased block.
|
2536
2892
|
#
|
2537
|
-
# @return [
|
2893
|
+
# @return [nil] nil
|
2538
2894
|
#
|
2539
|
-
def
|
2540
|
-
|
2895
|
+
def keyReleased(&block)
|
2896
|
+
@keyReleasedBlock__ = block if block
|
2897
|
+
nil
|
2541
2898
|
end
|
2542
2899
|
|
2543
|
-
#
|
2544
|
-
#
|
2545
|
-
# @param value [Numeric] number
|
2900
|
+
# Defines keyTyped block.
|
2546
2901
|
#
|
2547
|
-
# @return [
|
2902
|
+
# @return [nil] nil
|
2548
2903
|
#
|
2549
|
-
def
|
2550
|
-
|
2904
|
+
def keyTyped(&block)
|
2905
|
+
@keyTypedBlock__ = block if block
|
2906
|
+
nil
|
2551
2907
|
end
|
2552
2908
|
|
2553
|
-
#
|
2554
|
-
#
|
2555
|
-
# @overload mag(x, y)
|
2556
|
-
# @overload mag(x, y, z)
|
2557
|
-
#
|
2558
|
-
# @param x [Numeric] x of point
|
2559
|
-
# @param y [Numeric] y of point
|
2560
|
-
# @param z [Numeric] z of point
|
2909
|
+
# Defines mousePressed block.
|
2561
2910
|
#
|
2562
|
-
# @return [
|
2911
|
+
# @return [Boolean] is any mouse button pressed or not
|
2563
2912
|
#
|
2564
|
-
def
|
2565
|
-
|
2566
|
-
|
2567
|
-
when 2 then Math.sqrt x * x + y * y
|
2568
|
-
when 3 then Math.sqrt x * x + y * y + z * z
|
2569
|
-
else raise ArgumentError
|
2570
|
-
end
|
2913
|
+
def mousePressed(&block)
|
2914
|
+
@mousePressedBlock__ = block if block
|
2915
|
+
not @pointersPressed__.empty?
|
2571
2916
|
end
|
2572
2917
|
|
2573
|
-
#
|
2574
|
-
#
|
2575
|
-
# @overload dist(x1, y1, x2, y2)
|
2576
|
-
# @overload dist(x1, y1, z1, x2, y2, z2)
|
2577
|
-
#
|
2578
|
-
# @param x1 [Numeric] x of first point
|
2579
|
-
# @param y1 [Numeric] y of first point
|
2580
|
-
# @param z1 [Numeric] z of first point
|
2581
|
-
# @param x2 [Numeric] x of second point
|
2582
|
-
# @param y2 [Numeric] y of second point
|
2583
|
-
# @param z2 [Numeric] z of second point
|
2918
|
+
# Defines mouseReleased block.
|
2584
2919
|
#
|
2585
|
-
# @return [
|
2920
|
+
# @return [nil] nil
|
2586
2921
|
#
|
2587
|
-
def
|
2588
|
-
|
2589
|
-
|
2590
|
-
x1, y1, x2, y2 = *args
|
2591
|
-
xx, yy = x2 - x1, y2 - y1
|
2592
|
-
Math.sqrt xx * xx + yy * yy
|
2593
|
-
when 3
|
2594
|
-
x1, y1, z1, x2, y2, z2 = *args
|
2595
|
-
xx, yy, zz = x2 - x1, y2 - y1, z2 - z1
|
2596
|
-
Math.sqrt xx * xx + yy * yy + zz * zz
|
2597
|
-
else raise ArgumentError
|
2598
|
-
end
|
2922
|
+
def mouseReleased(&block)
|
2923
|
+
@mouseReleasedBlock__ = block if block
|
2924
|
+
nil
|
2599
2925
|
end
|
2600
2926
|
|
2601
|
-
#
|
2602
|
-
#
|
2603
|
-
# @param value [Numeric] number to be normalized
|
2604
|
-
# @param start [Numeric] lower bound of the range
|
2605
|
-
# @param stop [Numeric] upper bound of the range
|
2927
|
+
# Defines mouseMoved block.
|
2606
2928
|
#
|
2607
|
-
# @return [
|
2929
|
+
# @return [nil] nil
|
2608
2930
|
#
|
2609
|
-
def
|
2610
|
-
|
2931
|
+
def mouseMoved(&block)
|
2932
|
+
@mouseMovedBlock__ = block if block
|
2933
|
+
nil
|
2611
2934
|
end
|
2612
2935
|
|
2613
|
-
#
|
2614
|
-
#
|
2615
|
-
# @param start [Numeric] lower bound of the range
|
2616
|
-
# @param stop [Numeric] upper bound of the range
|
2617
|
-
# @param amount [Numeric] amount to interpolate
|
2936
|
+
# Defines mouseDragged block.
|
2618
2937
|
#
|
2619
|
-
# @return [
|
2938
|
+
# @return [nil] nil
|
2620
2939
|
#
|
2621
|
-
def
|
2622
|
-
|
2940
|
+
def mouseDragged(&block)
|
2941
|
+
@mouseDraggedBlock__ = block if block
|
2942
|
+
nil
|
2623
2943
|
end
|
2624
2944
|
|
2625
|
-
#
|
2626
|
-
#
|
2627
|
-
# @param value [Numeric] number to be mapped
|
2628
|
-
# @param start1 [Numeric] lower bound of the range1
|
2629
|
-
# @param stop1 [Numeric] upper bound of the range1
|
2630
|
-
# @param start2 [Numeric] lower bound of the range2
|
2631
|
-
# @param stop2 [Numeric] upper bound of the range2
|
2945
|
+
# Defines mouseClicked block.
|
2632
2946
|
#
|
2633
|
-
# @return [
|
2947
|
+
# @return [nil] nil
|
2634
2948
|
#
|
2635
|
-
def
|
2636
|
-
|
2949
|
+
def mouseClicked(&block)
|
2950
|
+
@mouseClickedBlock__ = block if block
|
2951
|
+
nil
|
2637
2952
|
end
|
2638
2953
|
|
2639
|
-
#
|
2640
|
-
#
|
2641
|
-
# @overload min(a, b)
|
2642
|
-
# @overload min(a, b, c)
|
2643
|
-
# @overload min(array)
|
2644
|
-
#
|
2645
|
-
# @param a [Numeric] value to compare
|
2646
|
-
# @param b [Numeric] value to compare
|
2647
|
-
# @param c [Numeric] value to compare
|
2648
|
-
# @param array [Numeric] values to compare
|
2954
|
+
# Defines touchStarted block.
|
2649
2955
|
#
|
2650
|
-
# @return [
|
2956
|
+
# @return [nil] nil
|
2651
2957
|
#
|
2652
|
-
def
|
2653
|
-
|
2958
|
+
def touchStarted(&block)
|
2959
|
+
@touchStartedBlock__ = block if block
|
2960
|
+
nil
|
2654
2961
|
end
|
2655
2962
|
|
2656
|
-
#
|
2657
|
-
#
|
2658
|
-
# @overload max(a, b)
|
2659
|
-
# @overload max(a, b, c)
|
2660
|
-
# @overload max(array)
|
2661
|
-
#
|
2662
|
-
# @param a [Numeric] value to compare
|
2663
|
-
# @param b [Numeric] value to compare
|
2664
|
-
# @param c [Numeric] value to compare
|
2665
|
-
# @param array [Numeric] values to compare
|
2963
|
+
# Defines touchEnded block.
|
2666
2964
|
#
|
2667
|
-
# @return [
|
2965
|
+
# @return [nil] nil
|
2668
2966
|
#
|
2669
|
-
def
|
2670
|
-
|
2967
|
+
def touchEnded(&block)
|
2968
|
+
@touchEndedBlock__ = block if block
|
2969
|
+
nil
|
2671
2970
|
end
|
2672
2971
|
|
2673
|
-
#
|
2674
|
-
#
|
2675
|
-
# @param value [Numeric] number to be constrained
|
2676
|
-
# @param min [Numeric] lower bound of the range
|
2677
|
-
# @param max [Numeric] upper bound of the range
|
2972
|
+
# Defines touchMoved block.
|
2678
2973
|
#
|
2679
|
-
# @return [
|
2974
|
+
# @return [nil] nil
|
2680
2975
|
#
|
2681
|
-
def
|
2682
|
-
|
2976
|
+
def touchMoved(&block)
|
2977
|
+
@touchMovedBlock__ = block if block
|
2978
|
+
nil
|
2683
2979
|
end
|
2684
2980
|
|
2685
|
-
#
|
2686
|
-
#
|
2687
|
-
# @param degree [Numeric] degree to convert
|
2981
|
+
# Defines motion block.
|
2688
2982
|
#
|
2689
|
-
# @return [
|
2983
|
+
# @return [nil] nil
|
2690
2984
|
#
|
2691
|
-
def
|
2692
|
-
|
2985
|
+
def motion(&block)
|
2986
|
+
@motionBlock__ = block if block
|
2987
|
+
nil
|
2693
2988
|
end
|
2694
2989
|
|
2695
|
-
#
|
2990
|
+
# Changes canvas size.
|
2696
2991
|
#
|
2697
|
-
# @param
|
2992
|
+
# @param width [Integer] new width
|
2993
|
+
# @param height [Integer] new height
|
2994
|
+
# @param pixelDensity [Numeric] new pixel density
|
2698
2995
|
#
|
2699
|
-
# @return [
|
2996
|
+
# @return [nil] nil
|
2700
2997
|
#
|
2701
|
-
def
|
2702
|
-
|
2998
|
+
def size(width, height, pixelDensity: self.pixelDensity)
|
2999
|
+
resizeCanvas__ :size, width, height, pixelDensity
|
3000
|
+
nil
|
2703
3001
|
end
|
2704
3002
|
|
2705
|
-
#
|
3003
|
+
# Changes canvas size.
|
2706
3004
|
#
|
2707
|
-
# @param
|
3005
|
+
# @param width [Integer] new width
|
3006
|
+
# @param height [Integer] new height
|
3007
|
+
# @param pixelDensity [Numeric] new pixel density
|
2708
3008
|
#
|
2709
|
-
# @return [
|
3009
|
+
# @return [nil] nil
|
2710
3010
|
#
|
2711
|
-
def
|
2712
|
-
|
3011
|
+
def createCanvas(width, height, pixelDensity: self.pixelDensity)
|
3012
|
+
resizeCanvas__ :createCanvas, width, height, pixelDensity
|
3013
|
+
nil
|
2713
3014
|
end
|
2714
3015
|
|
2715
|
-
#
|
3016
|
+
# Changes title of window.
|
2716
3017
|
#
|
2717
|
-
# @param
|
3018
|
+
# @param title [String] new title
|
2718
3019
|
#
|
2719
|
-
# @return [
|
3020
|
+
# @return [nil] nil
|
2720
3021
|
#
|
2721
|
-
def
|
2722
|
-
|
3022
|
+
def setTitle(title)
|
3023
|
+
@window__.title = title
|
3024
|
+
nil
|
2723
3025
|
end
|
2724
3026
|
|
2725
|
-
#
|
3027
|
+
# Changes and returns canvas pixel density.
|
2726
3028
|
#
|
2727
|
-
# @param
|
3029
|
+
# @param density [Numeric] new pixel density
|
2728
3030
|
#
|
2729
|
-
# @return [Numeric]
|
3031
|
+
# @return [Numeric] current pixel density
|
2730
3032
|
#
|
2731
|
-
def
|
2732
|
-
|
3033
|
+
def pixelDensity(density = nil)
|
3034
|
+
resizeCanvas__ :pixelDensity, width, height, density if density
|
3035
|
+
@painter__.pixel_density
|
2733
3036
|
end
|
2734
3037
|
|
2735
|
-
#
|
2736
|
-
|
2737
|
-
|
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.
|
2738
3050
|
#
|
2739
|
-
# @return [Numeric]
|
3051
|
+
# @return [Numeric] pixel density
|
2740
3052
|
#
|
2741
|
-
def
|
2742
|
-
|
3053
|
+
def displayDensity()
|
3054
|
+
@window__.painter.pixel_density
|
2743
3055
|
end
|
2744
3056
|
|
2745
|
-
# Returns
|
2746
|
-
#
|
2747
|
-
# @param value [Numeric] value for calculation
|
3057
|
+
# Returns window width.
|
2748
3058
|
#
|
2749
|
-
# @return [Numeric]
|
3059
|
+
# @return [Numeric] window width
|
2750
3060
|
#
|
2751
|
-
def
|
2752
|
-
|
3061
|
+
def windowWidth()
|
3062
|
+
@window__.width
|
2753
3063
|
end
|
2754
3064
|
|
2755
|
-
# Returns
|
2756
|
-
#
|
2757
|
-
# @param value [Numeric] value for valculation
|
3065
|
+
# Returns window height.
|
2758
3066
|
#
|
2759
|
-
# @return [Numeric]
|
3067
|
+
# @return [Numeric] window height
|
2760
3068
|
#
|
2761
|
-
def
|
2762
|
-
|
3069
|
+
def windowHeight()
|
3070
|
+
@window__.height
|
2763
3071
|
end
|
2764
3072
|
|
2765
|
-
# Returns
|
2766
|
-
#
|
2767
|
-
# @param y [Numeric] y of the point
|
2768
|
-
# @param x [Numeric] x of the point
|
3073
|
+
# Returns number of frames since program started.
|
2769
3074
|
#
|
2770
|
-
# @return [
|
3075
|
+
# @return [Integer] total number of frames
|
2771
3076
|
#
|
2772
|
-
def
|
2773
|
-
|
3077
|
+
def frameCount()
|
3078
|
+
@frameCount__
|
2774
3079
|
end
|
2775
3080
|
|
2776
|
-
# Returns
|
3081
|
+
# Returns number of frames per second.
|
2777
3082
|
#
|
2778
|
-
# @
|
2779
|
-
# @overload noise(x, y)
|
2780
|
-
# @overload noise(x, y, z)
|
3083
|
+
# @return [Float] frames per second
|
2781
3084
|
#
|
2782
|
-
|
2783
|
-
|
2784
|
-
|
3085
|
+
def frameRate()
|
3086
|
+
@window__.event.fps
|
3087
|
+
end
|
3088
|
+
|
3089
|
+
# Returns the last key that was pressed or released.
|
2785
3090
|
#
|
2786
|
-
# @return [
|
3091
|
+
# @return [String] last key
|
2787
3092
|
#
|
2788
|
-
def
|
2789
|
-
|
3093
|
+
def key()
|
3094
|
+
@key__
|
2790
3095
|
end
|
2791
3096
|
|
2792
|
-
# Returns
|
3097
|
+
# Returns the last key code that was pressed or released.
|
2793
3098
|
#
|
2794
|
-
# @
|
2795
|
-
# @overload random(high)
|
2796
|
-
# @overload random(low, high)
|
2797
|
-
# @overload random(choices)
|
3099
|
+
# @return [Symbol] last key code
|
2798
3100
|
#
|
2799
|
-
|
2800
|
-
|
2801
|
-
|
3101
|
+
def keyCode()
|
3102
|
+
@keyCode__
|
3103
|
+
end
|
3104
|
+
|
3105
|
+
# Returns mouse x position
|
2802
3106
|
#
|
2803
|
-
# @return [
|
3107
|
+
# @return [Numeric] horizontal position of mouse
|
2804
3108
|
#
|
2805
|
-
def
|
2806
|
-
|
2807
|
-
high, low = args.reverse
|
2808
|
-
rand (low || 0).to_f...(high || 1).to_f
|
3109
|
+
def mouseX()
|
3110
|
+
@pointerPos__.x
|
2809
3111
|
end
|
2810
3112
|
|
2811
|
-
#
|
3113
|
+
# Returns mouse y position
|
2812
3114
|
#
|
2813
|
-
# @
|
2814
|
-
# @overload createVector(x, y)
|
2815
|
-
# @overload createVector(x, y, z)
|
3115
|
+
# @return [Numeric] vertical position of mouse
|
2816
3116
|
#
|
2817
|
-
|
2818
|
-
|
2819
|
-
|
3117
|
+
def mouseY()
|
3118
|
+
@pointerPos__.y
|
3119
|
+
end
|
3120
|
+
|
3121
|
+
# Returns mouse x position in previous frame
|
2820
3122
|
#
|
2821
|
-
# @return [
|
3123
|
+
# @return [Numeric] horizontal position of mouse
|
2822
3124
|
#
|
2823
|
-
def
|
2824
|
-
|
3125
|
+
def pmouseX()
|
3126
|
+
@pointerPrevPos__.x
|
2825
3127
|
end
|
2826
3128
|
|
2827
|
-
#
|
3129
|
+
# Returns mouse y position in previous frame
|
2828
3130
|
#
|
2829
|
-
# @
|
2830
|
-
# @overload createImage(w, h, format)
|
3131
|
+
# @return [Numeric] vertical position of mouse
|
2831
3132
|
#
|
2832
|
-
|
2833
|
-
|
2834
|
-
|
3133
|
+
def pmouseY()
|
3134
|
+
@pointerPrevPos__.y
|
3135
|
+
end
|
3136
|
+
|
3137
|
+
# Returns which mouse button was pressed
|
2835
3138
|
#
|
2836
|
-
# @return [
|
3139
|
+
# @return [Numeric] LEFT, RIGHT, CENTER or 0
|
2837
3140
|
#
|
2838
|
-
def
|
2839
|
-
|
2840
|
-
raise ArgumentError, "Unknown image format" unless colorspace
|
2841
|
-
Image.new Rays::Image.new(w, h, colorspace).paint {background 0, 0}
|
3141
|
+
def mouseButton()
|
3142
|
+
(@pointersPressed__ & [LEFT, RIGHT, CENTER]).last || 0
|
2842
3143
|
end
|
2843
3144
|
|
2844
|
-
#
|
3145
|
+
# Returns array of touches
|
2845
3146
|
#
|
2846
|
-
# @return [
|
3147
|
+
# @return [Array] Touch objects
|
2847
3148
|
#
|
2848
|
-
def
|
2849
|
-
|
3149
|
+
def touches()
|
3150
|
+
@touches__
|
2850
3151
|
end
|
2851
3152
|
|
2852
|
-
#
|
2853
|
-
#
|
2854
|
-
# @param width [Numeric] width of graphics image
|
2855
|
-
# @param height [Numeric] height of graphics image
|
3153
|
+
# Returns vector for real world gravity
|
2856
3154
|
#
|
2857
|
-
# @return [
|
3155
|
+
# @return [Vector] gravity vector
|
2858
3156
|
#
|
2859
|
-
def
|
2860
|
-
|
3157
|
+
def motionGravity()
|
3158
|
+
@motionGravity__
|
2861
3159
|
end
|
2862
3160
|
|
2863
|
-
#
|
2864
|
-
#
|
2865
|
-
# @param filename [String] file name to load image
|
2866
|
-
# @param extension [String] type of image to load (ex. 'png')
|
3161
|
+
# Enables calling draw block on every frame.
|
2867
3162
|
#
|
2868
|
-
# @return [
|
3163
|
+
# @return [nil] nil
|
2869
3164
|
#
|
2870
|
-
def
|
2871
|
-
|
2872
|
-
Image.new Rays::Image.load filename
|
3165
|
+
def loop()
|
3166
|
+
@loop__ = true
|
2873
3167
|
end
|
2874
3168
|
|
2875
|
-
#
|
2876
|
-
|
2877
|
-
|
2878
|
-
|
2879
|
-
|
2880
|
-
|
2881
|
-
path = tmpdir + Digest::SHA1.hexdigest(uri)
|
2882
|
-
path = path.sub_ext ext
|
2883
|
-
|
2884
|
-
unless path.file?
|
2885
|
-
URI.open uri do |input|
|
2886
|
-
input.set_encoding nil# disable default_internal
|
2887
|
-
tmpdir.mkdir unless tmpdir.directory?
|
2888
|
-
path.open('w') do |output|
|
2889
|
-
output.set_encoding Encoding::ASCII_8BIT
|
2890
|
-
while buf = input.read(2 ** 16)
|
2891
|
-
output.write buf
|
2892
|
-
end
|
2893
|
-
end
|
2894
|
-
end
|
2895
|
-
end
|
2896
|
-
path.to_s
|
3169
|
+
# Disables calling draw block on every frame.
|
3170
|
+
#
|
3171
|
+
# @return [nil] nil
|
3172
|
+
#
|
3173
|
+
def noLoop()
|
3174
|
+
@loop__ = false
|
2897
3175
|
end
|
2898
3176
|
|
2899
|
-
#
|
2900
|
-
|
2901
|
-
|
3177
|
+
# Calls draw block to redraw frame.
|
3178
|
+
#
|
3179
|
+
# @return [nil] nil
|
3180
|
+
#
|
3181
|
+
def redraw()
|
3182
|
+
@redraw__ = true
|
2902
3183
|
end
|
2903
3184
|
|
2904
3185
|
end# Context
|