propane 3.9.0-java → 3.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +2 -2
  4. data/README.md +3 -3
  5. data/Rakefile +6 -6
  6. data/lib/java/japplemenubar/JAppleMenuBar.java +88 -0
  7. data/lib/java/japplemenubar/libjAppleMenuBar.jnilib +0 -0
  8. data/lib/java/monkstone/ColorUtil.java +127 -0
  9. data/lib/java/monkstone/MathToolModule.java +287 -0
  10. data/lib/java/monkstone/PropaneLibrary.java +46 -0
  11. data/lib/java/monkstone/core/LibraryProxy.java +136 -0
  12. data/lib/java/monkstone/fastmath/DegLutTables.java +111 -0
  13. data/lib/java/monkstone/fastmath/Deglut.java +71 -0
  14. data/lib/java/monkstone/fastmath/package-info.java +6 -0
  15. data/lib/java/monkstone/filechooser/Chooser.java +39 -0
  16. data/{src/main → lib}/java/monkstone/noise/FastTerrain.java +0 -0
  17. data/{src/main → lib}/java/monkstone/noise/Noise.java +0 -0
  18. data/{src/main → lib}/java/monkstone/noise/NoiseGenerator.java +0 -0
  19. data/{src/main → lib}/java/monkstone/noise/NoiseMode.java +0 -0
  20. data/lib/java/monkstone/noise/OpenSimplex2F.java +881 -0
  21. data/lib/java/monkstone/noise/OpenSimplex2S.java +1106 -0
  22. data/{src/main → lib}/java/monkstone/noise/SmoothTerrain.java +0 -0
  23. data/lib/java/monkstone/slider/CustomHorizontalSlider.java +164 -0
  24. data/lib/java/monkstone/slider/CustomVerticalSlider.java +178 -0
  25. data/lib/java/monkstone/slider/SimpleHorizontalSlider.java +145 -0
  26. data/lib/java/monkstone/slider/SimpleSlider.java +166 -0
  27. data/lib/java/monkstone/slider/SimpleVerticalSlider.java +157 -0
  28. data/lib/java/monkstone/slider/Slider.java +61 -0
  29. data/lib/java/monkstone/slider/SliderBar.java +245 -0
  30. data/lib/java/monkstone/slider/SliderGroup.java +56 -0
  31. data/lib/java/monkstone/slider/WheelHandler.java +35 -0
  32. data/lib/java/monkstone/vecmath/GfxRender.java +86 -0
  33. data/lib/java/monkstone/vecmath/JRender.java +56 -0
  34. data/lib/java/monkstone/vecmath/ShapeRender.java +87 -0
  35. data/lib/java/monkstone/vecmath/package-info.java +20 -0
  36. data/lib/java/monkstone/vecmath/vec2/Vec2.java +802 -0
  37. data/lib/java/monkstone/vecmath/vec2/package-info.java +6 -0
  38. data/lib/java/monkstone/vecmath/vec3/Vec3.java +727 -0
  39. data/lib/java/monkstone/vecmath/vec3/package-info.java +6 -0
  40. data/lib/java/monkstone/videoevent/CaptureEvent.java +27 -0
  41. data/lib/java/monkstone/videoevent/MovieEvent.java +32 -0
  42. data/lib/java/monkstone/videoevent/package-info.java +20 -0
  43. data/lib/java/processing/awt/PGraphicsJava2D.java +3040 -0
  44. data/lib/java/processing/awt/PImageAWT.java +377 -0
  45. data/lib/java/processing/awt/PShapeJava2D.java +387 -0
  46. data/lib/java/processing/awt/PSurfaceAWT.java +1581 -0
  47. data/lib/java/processing/awt/ShimAWT.java +581 -0
  48. data/lib/java/processing/core/PApplet.java +15156 -0
  49. data/lib/java/processing/core/PConstants.java +523 -0
  50. data/lib/java/processing/core/PFont.java +1126 -0
  51. data/lib/java/processing/core/PGraphics.java +8600 -0
  52. data/lib/java/processing/core/PImage.java +3377 -0
  53. data/lib/java/processing/core/PMatrix.java +208 -0
  54. data/lib/java/processing/core/PMatrix2D.java +562 -0
  55. data/lib/java/processing/core/PMatrix3D.java +890 -0
  56. data/lib/java/processing/core/PShape.java +3561 -0
  57. data/lib/java/processing/core/PShapeOBJ.java +483 -0
  58. data/lib/java/processing/core/PShapeSVG.java +2016 -0
  59. data/lib/java/processing/core/PStyle.java +63 -0
  60. data/lib/java/processing/core/PSurface.java +198 -0
  61. data/lib/java/processing/core/PSurfaceNone.java +431 -0
  62. data/lib/java/processing/core/PVector.java +1066 -0
  63. data/lib/java/processing/core/ThinkDifferent.java +115 -0
  64. data/lib/java/processing/data/DoubleDict.java +850 -0
  65. data/lib/java/processing/data/DoubleList.java +928 -0
  66. data/lib/java/processing/data/FloatDict.java +847 -0
  67. data/lib/java/processing/data/FloatList.java +936 -0
  68. data/lib/java/processing/data/IntDict.java +807 -0
  69. data/lib/java/processing/data/IntList.java +936 -0
  70. data/lib/java/processing/data/JSONArray.java +1260 -0
  71. data/lib/java/processing/data/JSONObject.java +2282 -0
  72. data/lib/java/processing/data/JSONTokener.java +435 -0
  73. data/lib/java/processing/data/LongDict.java +802 -0
  74. data/lib/java/processing/data/LongList.java +937 -0
  75. data/lib/java/processing/data/Sort.java +46 -0
  76. data/lib/java/processing/data/StringDict.java +613 -0
  77. data/lib/java/processing/data/StringList.java +800 -0
  78. data/lib/java/processing/data/Table.java +4936 -0
  79. data/lib/java/processing/data/TableRow.java +198 -0
  80. data/lib/java/processing/data/XML.java +1156 -0
  81. data/lib/java/processing/dxf/RawDXF.java +404 -0
  82. data/lib/java/processing/event/Event.java +125 -0
  83. data/lib/java/processing/event/KeyEvent.java +70 -0
  84. data/lib/java/processing/event/MouseEvent.java +114 -0
  85. data/lib/java/processing/event/TouchEvent.java +57 -0
  86. data/lib/java/processing/javafx/PGraphicsFX2D.java +32 -0
  87. data/lib/java/processing/javafx/PSurfaceFX.java +173 -0
  88. data/lib/java/processing/net/Client.java +744 -0
  89. data/lib/java/processing/net/Server.java +388 -0
  90. data/lib/java/processing/opengl/FontTexture.java +378 -0
  91. data/lib/java/processing/opengl/FrameBuffer.java +513 -0
  92. data/lib/java/processing/opengl/LinePath.java +627 -0
  93. data/lib/java/processing/opengl/LineStroker.java +681 -0
  94. data/lib/java/processing/opengl/PGL.java +3483 -0
  95. data/lib/java/processing/opengl/PGraphics2D.java +615 -0
  96. data/lib/java/processing/opengl/PGraphics3D.java +281 -0
  97. data/lib/java/processing/opengl/PGraphicsOpenGL.java +13753 -0
  98. data/lib/java/processing/opengl/PJOGL.java +2008 -0
  99. data/lib/java/processing/opengl/PShader.java +1484 -0
  100. data/lib/java/processing/opengl/PShapeOpenGL.java +5269 -0
  101. data/lib/java/processing/opengl/PSurfaceJOGL.java +1385 -0
  102. data/lib/java/processing/opengl/Texture.java +1696 -0
  103. data/lib/java/processing/opengl/VertexBuffer.java +88 -0
  104. data/lib/java/processing/opengl/cursors/arrow.png +0 -0
  105. data/lib/java/processing/opengl/cursors/cross.png +0 -0
  106. data/lib/java/processing/opengl/cursors/hand.png +0 -0
  107. data/lib/java/processing/opengl/cursors/license.txt +27 -0
  108. data/lib/java/processing/opengl/cursors/move.png +0 -0
  109. data/lib/java/processing/opengl/cursors/text.png +0 -0
  110. data/lib/java/processing/opengl/cursors/wait.png +0 -0
  111. data/lib/java/processing/opengl/shaders/ColorFrag.glsl +32 -0
  112. data/lib/java/processing/opengl/shaders/ColorVert.glsl +34 -0
  113. data/lib/java/processing/opengl/shaders/LightFrag.glsl +33 -0
  114. data/lib/java/processing/opengl/shaders/LightVert.glsl +151 -0
  115. data/lib/java/processing/opengl/shaders/LineFrag.glsl +32 -0
  116. data/lib/java/processing/opengl/shaders/LineVert.glsl +100 -0
  117. data/lib/java/processing/opengl/shaders/MaskFrag.glsl +40 -0
  118. data/lib/java/processing/opengl/shaders/PointFrag.glsl +32 -0
  119. data/lib/java/processing/opengl/shaders/PointVert.glsl +56 -0
  120. data/lib/java/processing/opengl/shaders/TexFrag.glsl +37 -0
  121. data/lib/java/processing/opengl/shaders/TexLightFrag.glsl +37 -0
  122. data/lib/java/processing/opengl/shaders/TexLightVert.glsl +157 -0
  123. data/lib/java/processing/opengl/shaders/TexVert.glsl +38 -0
  124. data/lib/java/processing/pdf/PGraphicsPDF.java +581 -0
  125. data/lib/java/processing/svg/PGraphicsSVG.java +378 -0
  126. data/lib/propane/app.rb +8 -13
  127. data/lib/propane/version.rb +1 -1
  128. data/mvnw +3 -3
  129. data/mvnw.cmd +2 -2
  130. data/pom.rb +7 -2
  131. data/pom.xml +14 -2
  132. data/propane.gemspec +2 -2
  133. data/src/main/java/monkstone/FastNoiseModuleJava.java +127 -0
  134. data/src/main/java/monkstone/MathToolModule.java +30 -30
  135. data/src/main/java/monkstone/PropaneLibrary.java +2 -0
  136. data/src/main/java/monkstone/SmoothNoiseModuleJava.java +127 -0
  137. data/src/main/java/monkstone/fastmath/DegLutTables.java +15 -15
  138. data/src/main/java/monkstone/filechooser/Chooser.java +1 -1
  139. data/src/main/java/monkstone/noise/OpenSimplex2F.java +752 -820
  140. data/src/main/java/monkstone/noise/OpenSimplex2S.java +1138 -1106
  141. data/src/main/java/monkstone/slider/WheelHandler.java +1 -1
  142. data/src/main/java/monkstone/vecmath/JRender.java +6 -6
  143. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +20 -19
  144. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +12 -12
  145. data/src/main/java/processing/awt/PGraphicsJava2D.java +11 -3
  146. data/src/main/java/processing/core/PApplet.java +89 -89
  147. data/src/main/java/processing/core/PConstants.java +155 -163
  148. data/src/main/java/processing/opengl/PJOGL.java +6 -5
  149. data/vendors/Rakefile +1 -1
  150. metadata +136 -19
@@ -0,0 +1,3561 @@
1
+ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
+
3
+ /*
4
+ Part of the Processing project - http://processing.org
5
+
6
+ Copyright (c) 2006-10 Ben Fry and Casey Reas
7
+
8
+ This library is free software; you can redistribute it and/or
9
+ modify it under the terms of the GNU Lesser General Public
10
+ License version 2.1 as published by the Free Software Foundation.
11
+
12
+ This library is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General
18
+ Public License along with this library; if not, write to the
19
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20
+ Boston, MA 02111-1307 USA
21
+ */
22
+
23
+ package processing.core;
24
+
25
+ import java.awt.Image;
26
+ import java.awt.color.ColorSpace;
27
+ import java.awt.image.BufferedImage;
28
+ import java.util.HashMap;
29
+ import java.util.Map;
30
+
31
+ import javax.swing.ImageIcon;
32
+
33
+ import processing.awt.PImageAWT;
34
+
35
+ import java.util.Base64;
36
+
37
+
38
+ /**
39
+ * ( begin auto-generated from PShape.xml )
40
+ *
41
+ * Datatype for storing shapes. Processing can currently load and display
42
+ * SVG (Scalable Vector Graphics) shapes. Before a shape is used, it must
43
+ * be loaded with the <b>loadShape()</b> function. The <b>shape()</b>
44
+ * function is used to draw the shape to the display window. The
45
+ * <b>PShape</b> object contain a group of methods, linked below, that can
46
+ * operate on the shape data.
47
+ *
48
+ * The <b>loadShape()</b> function supports SVG files created with Inkscape
49
+ * and Adobe Illustrator. It is not a full SVG implementation, but offers
50
+ * some straightforward support for handling vector data.
51
+ *
52
+ * ( end auto-generated )
53
+ * <h3>Advanced</h3>
54
+ *
55
+ * In-progress class to handle shape data, currently to be considered of
56
+ * alpha or beta quality. Major structural work may be performed on this class
57
+ * after the release of Processing 1.0. Such changes may include:
58
+ *
59
+ * <ul>
60
+ * <li> addition of proper accessors to read shape vertex and coloring data
61
+ * (this is the second most important part of having a PShape class after all).
62
+ * <li> a means of creating PShape objects ala beginShape() and endShape().
63
+ * <li> load(), update(), and cache methods ala PImage, so that shapes can
64
+ * have renderer-specific optimizations, such as vertex arrays in OpenGL.
65
+ * <li> splitting this class into multiple classes to handle different
66
+ * varieties of shape data (primitives vs collections of vertices vs paths)
67
+ * <li> change of package declaration, for instance moving the code into
68
+ * package processing.shape (if the code grows too much).
69
+ * </ul>
70
+ *
71
+ * <p>For the time being, this class and its shape() and loadShape() friends in
72
+ * PApplet exist as placeholders for more exciting things to come. If you'd
73
+ * like to work with this class, make a subclass (see how PShapeSVG works)
74
+ * and you can play with its internal methods all you like.</p>
75
+ *
76
+ * <p>Library developers are encouraged to create PShape objects when loading
77
+ * shape data, so that they can eventually hook into the bounty that will be
78
+ * the PShape interface, and the ease of loadShape() and shape().</p>
79
+ *
80
+ * @webref shape
81
+ * @usage Web &amp; Application
82
+ * @see PApplet#loadShape(String)
83
+ * @see PApplet#createShape()
84
+ * @see PApplet#shapeMode(int)
85
+ * @instanceName sh any variable of type PShape
86
+ */
87
+ public class PShape implements PConstants {
88
+ protected String name;
89
+ protected Map<String,PShape> nameTable;
90
+
91
+ // /** Generic, only draws its child objects. */
92
+ // static public final int GROUP = 0;
93
+ // GROUP now inherited from PConstants, and is still zero
94
+
95
+ // These constants were updated in 3.0b6 so that they could be distinguished
96
+ // from others in PConstants and improve how some typos were handled.
97
+ // https://github.com/processing/processing/issues/3776
98
+ /** A line, ellipse, arc, image, etc. */
99
+ static public final int PRIMITIVE = 101;
100
+ /** A series of vertex, curveVertex, and bezierVertex calls. */
101
+ static public final int PATH = 102;
102
+ /** Collections of vertices created with beginShape(). */
103
+ static public final int GEOMETRY = 103;
104
+ /** The shape type, one of GROUP, PRIMITIVE, PATH, or GEOMETRY. */
105
+ protected int family;
106
+
107
+ /** ELLIPSE, LINE, QUAD; TRIANGLE_FAN, QUAD_STRIP; etc. */
108
+ protected int kind;
109
+
110
+ protected PMatrix matrix;
111
+
112
+ protected int textureMode;
113
+
114
+ /** Texture or image data associated with this shape. */
115
+ protected PImage image;
116
+ protected String imagePath = null;
117
+
118
+ public static final String OUTSIDE_BEGIN_END_ERROR =
119
+ "%1$s can only be called between beginShape() and endShape()";
120
+
121
+ public static final String INSIDE_BEGIN_END_ERROR =
122
+ "%1$s can only be called outside beginShape() and endShape()";
123
+
124
+ public static final String NO_SUCH_VERTEX_ERROR =
125
+ "%1$s vertex index does not exist";
126
+
127
+ static public final String NO_VERTICES_ERROR =
128
+ "getVertexCount() only works with PATH or GEOMETRY shapes";
129
+
130
+ public static final String NOT_A_SIMPLE_VERTEX =
131
+ "%1$s can not be called on quadratic or bezier vertices";
132
+
133
+ static public final String PER_VERTEX_UNSUPPORTED =
134
+ "This renderer does not support %1$s for individual vertices";
135
+
136
+ /**
137
+ * ( begin auto-generated from PShape_width.xml )
138
+ *
139
+ * The width of the PShape document.
140
+ *
141
+ * ( end auto-generated )
142
+ * @webref pshape:field
143
+ * @usage web_application
144
+ * @brief Shape document width
145
+ * @see PShape#height
146
+ */
147
+ public float width;
148
+ /**
149
+ * ( begin auto-generated from PShape_height.xml )
150
+ *
151
+ * The height of the PShape document.
152
+ *
153
+ * ( end auto-generated )
154
+ * @webref pshape:field
155
+ * @usage web_application
156
+ * @brief Shape document height
157
+ * @see PShape#width
158
+ */
159
+ public float height;
160
+
161
+ public float depth;
162
+
163
+ PGraphics g;
164
+
165
+ // set to false if the object is hidden in the layers palette
166
+ protected boolean visible = true;
167
+
168
+ /** Retained shape being created with beginShape/endShape */
169
+ protected boolean openShape = false;
170
+
171
+ protected boolean openContour = false;
172
+
173
+ protected boolean stroke;
174
+ protected int strokeColor;
175
+ protected float strokeWeight; // default is 1
176
+ protected int strokeCap;
177
+ protected int strokeJoin;
178
+
179
+ protected boolean fill;
180
+ protected int fillColor;
181
+
182
+ protected boolean tint;
183
+ protected int tintColor;
184
+
185
+ protected int ambientColor;
186
+ protected boolean setAmbient;
187
+ protected int specularColor;
188
+ protected int emissiveColor;
189
+ protected float shininess;
190
+
191
+ protected int sphereDetailU, sphereDetailV;
192
+ protected int rectMode;
193
+ protected int ellipseMode;
194
+
195
+ /** Temporary toggle for whether styles should be honored. */
196
+ protected boolean style = true;
197
+
198
+ /** For primitive shapes in particular, params like x/y/w/h or x1/y1/x2/y2. */
199
+ protected float[] params;
200
+
201
+ protected int vertexCount;
202
+ /**
203
+ * When drawing POLYGON shapes, the second param is an array of length
204
+ * VERTEX_FIELD_COUNT. When drawing PATH shapes, the second param has only
205
+ * two variables.
206
+ */
207
+ protected float[][] vertices;
208
+
209
+ protected PShape parent;
210
+ protected int childCount;
211
+ protected PShape[] children;
212
+
213
+
214
+ /** Array of VERTEX, BEZIER_VERTEX, and CURVE_VERTEX calls. */
215
+ protected int vertexCodeCount;
216
+ protected int[] vertexCodes;
217
+ /** True if this is a closed path. */
218
+ protected boolean close;
219
+
220
+ // ........................................................
221
+
222
+ // internal color for setting/calculating
223
+ protected float calcR, calcG, calcB, calcA;
224
+ protected int calcRi, calcGi, calcBi, calcAi;
225
+ protected int calcColor;
226
+ protected boolean calcAlpha;
227
+
228
+ /** The current colorMode */
229
+ public int colorMode; // = RGB;
230
+
231
+ /** Max value for red (or hue) set by colorMode */
232
+ public float colorModeX; // = 255;
233
+
234
+ /** Max value for green (or saturation) set by colorMode */
235
+ public float colorModeY; // = 255;
236
+
237
+ /** Max value for blue (or value) set by colorMode */
238
+ public float colorModeZ; // = 255;
239
+
240
+ /** Max value for alpha set by colorMode */
241
+ public float colorModeA; // = 255;
242
+
243
+ /** True if colors are not in the range 0..1 */
244
+ boolean colorModeScale; // = true;
245
+
246
+ /** True if colorMode(RGB, 255) */
247
+ boolean colorModeDefault; // = true;
248
+
249
+ /** True if contains 3D data */
250
+ protected boolean is3D = false;
251
+
252
+ protected boolean perVertexStyles = false;
253
+
254
+ // should this be called vertices (consistent with PGraphics internals)
255
+ // or does that hurt flexibility?
256
+
257
+
258
+ // POINTS, LINES, xLINE_STRIP, xLINE_LOOP
259
+ // TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN
260
+ // QUADS, QUAD_STRIP
261
+ // xPOLYGON
262
+ // static final int PATH = 1; // POLYGON, LINE_LOOP, LINE_STRIP
263
+ // static final int GROUP = 2;
264
+
265
+ // how to handle rectmode/ellipsemode?
266
+ // are they bitshifted into the constant?
267
+ // CORNER, CORNERS, CENTER, (CENTER_RADIUS?)
268
+ // static final int RECT = 3; // could just be QUAD, but would be x1/y1/x2/y2
269
+ // static final int ELLIPSE = 4;
270
+ //
271
+ // static final int VERTEX = 7;
272
+ // static final int CURVE = 5;
273
+ // static final int BEZIER = 6;
274
+
275
+
276
+ // fill and stroke functions will need a pointer to the parent
277
+ // PGraphics object.. may need some kind of createShape() fxn
278
+ // or maybe the values are stored until draw() is called?
279
+
280
+ // attaching images is very tricky.. it's a different type of data
281
+
282
+ // material parameters will be thrown out,
283
+ // except those currently supported (kinds of lights)
284
+
285
+ // pivot point for transformations
286
+ // public float px;
287
+ // public float py;
288
+
289
+
290
+ /**
291
+ * @nowebref
292
+ */
293
+ public PShape() {
294
+ this.family = GROUP;
295
+ }
296
+
297
+
298
+ /**
299
+ * @nowebref
300
+ */
301
+ public PShape(int family) {
302
+ this.family = family;
303
+ }
304
+
305
+
306
+ /**
307
+ * @nowebref
308
+ */
309
+ public PShape(PGraphics g, int family) {
310
+ this.g = g;
311
+ this.family = family;
312
+
313
+ // Style parameters are retrieved from the current values in the renderer.
314
+ textureMode = g.textureMode;
315
+
316
+ colorMode(g.colorMode,
317
+ g.colorModeX, g.colorModeY, g.colorModeZ, g.colorModeA);
318
+
319
+ // Initial values for fill, stroke and tint colors are also imported from
320
+ // the renderer. This is particular relevant for primitive shapes, since is
321
+ // not possible to set their color separately when creating them, and their
322
+ // input vertices are actually generated at rendering time, by which the
323
+ // color configuration of the renderer might have changed.
324
+ fill = g.fill;
325
+ fillColor = g.fillColor;
326
+
327
+ stroke = g.stroke;
328
+ strokeColor = g.strokeColor;
329
+ strokeWeight = g.strokeWeight;
330
+ strokeCap = g.strokeCap;
331
+ strokeJoin = g.strokeJoin;
332
+
333
+ tint = g.tint;
334
+ tintColor = g.tintColor;
335
+
336
+ setAmbient = g.setAmbient;
337
+ ambientColor = g.ambientColor;
338
+ specularColor = g.specularColor;
339
+ emissiveColor = g.emissiveColor;
340
+ shininess = g.shininess;
341
+
342
+ sphereDetailU = g.sphereDetailU;
343
+ sphereDetailV = g.sphereDetailV;
344
+
345
+ // bezierDetail = pg.bezierDetail;
346
+ // curveDetail = pg.curveDetail;
347
+ // curveTightness = pg.curveTightness;
348
+
349
+ rectMode = g.rectMode;
350
+ ellipseMode = g.ellipseMode;
351
+
352
+ // normalX = normalY = 0;
353
+ // normalZ = 1;
354
+ //
355
+ // normalMode = NORMAL_MODE_AUTO;
356
+
357
+ // To make sure that the first vertex is marked as a break.
358
+ // Same behavior as in the immediate mode.
359
+ // breakShape = false;
360
+
361
+ if (family == GROUP) {
362
+ // GROUP shapes are always marked as ended.
363
+ // shapeCreated = true;
364
+ // TODO why was this commented out?
365
+ }
366
+ }
367
+
368
+
369
+ public PShape(PGraphics g, int kind, float... params) {
370
+ this(g, PRIMITIVE);
371
+ setKind(kind);
372
+ setParams(params);
373
+ }
374
+
375
+
376
+ public void setFamily(int family) {
377
+ this.family = family;
378
+ }
379
+
380
+
381
+ public void setKind(int kind) {
382
+ this.kind = kind;
383
+ }
384
+
385
+
386
+ public void setName(String name) {
387
+ this.name = name;
388
+ }
389
+
390
+
391
+ public String getName() {
392
+ return name;
393
+ }
394
+
395
+ /**
396
+ * ( begin auto-generated from PShape_isVisible.xml )
397
+ *
398
+ * Returns a boolean value "true" if the image is set to be visible,
399
+ * "false" if not. This is modified with the <b>setVisible()</b> parameter.
400
+ *
401
+ * The visibility of a shape is usually controlled by whatever program
402
+ * created the SVG file. For instance, this parameter is controlled by
403
+ * showing or hiding the shape in the layers palette in Adobe Illustrator.
404
+ *
405
+ * ( end auto-generated )
406
+ * @webref pshape:method
407
+ * @usage web_application
408
+ * @brief Returns a boolean value "true" if the image is set to be visible, "false" if not
409
+ * @see PShape#setVisible(boolean)
410
+ */
411
+ public boolean isVisible() {
412
+ return visible;
413
+ }
414
+
415
+
416
+ /**
417
+ * ( begin auto-generated from PShape_setVisible.xml )
418
+ *
419
+ * Sets the shape to be visible or invisible. This is determined by the
420
+ * value of the <b>visible</b> parameter.
421
+ *
422
+ * The visibility of a shape is usually controlled by whatever program
423
+ * created the SVG file. For instance, this parameter is controlled by
424
+ * showing or hiding the shape in the layers palette in Adobe Illustrator.
425
+ *
426
+ * ( end auto-generated )
427
+ * @webref pshape:mathod
428
+ * @usage web_application
429
+ * @brief Sets the shape to be visible or invisible
430
+ * @param visible "false" makes the shape invisible and "true" makes it visible
431
+ * @see PShape#isVisible()
432
+ */
433
+ public void setVisible(boolean visible) {
434
+ this.visible = visible;
435
+ }
436
+
437
+
438
+ /**
439
+ * ( begin auto-generated from PShape_disableStyle.xml )
440
+ *
441
+ * Disables the shape's style data and uses Processing's current styles.
442
+ * Styles include attributes such as colors, stroke weight, and stroke
443
+ * joints.
444
+ *
445
+ * ( end auto-generated )
446
+ * <h3>Advanced</h3>
447
+ * Overrides this shape's style information and uses PGraphics styles and
448
+ * colors. Identical to ignoreStyles(true). Also disables styles for all
449
+ * child shapes.
450
+ * @webref pshape:method
451
+ * @usage web_application
452
+ * @brief Disables the shape's style data and uses Processing styles
453
+ * @see PShape#enableStyle()
454
+ */
455
+ public void disableStyle() {
456
+ style = false;
457
+
458
+ for (int i = 0; i < childCount; i++) {
459
+ children[i].disableStyle();
460
+ }
461
+ }
462
+
463
+
464
+ /**
465
+ * ( begin auto-generated from PShape_enableStyle.xml )
466
+ *
467
+ * Enables the shape's style data and ignores Processing's current styles.
468
+ * Styles include attributes such as colors, stroke weight, and stroke
469
+ * joints.
470
+ *
471
+ * ( end auto-generated )
472
+ *
473
+ * @webref pshape:method
474
+ * @usage web_application
475
+ * @brief Enables the shape's style data and ignores the Processing styles
476
+ * @see PShape#disableStyle()
477
+ */
478
+ public void enableStyle() {
479
+ style = true;
480
+
481
+ for (int i = 0; i < childCount; i++) {
482
+ children[i].enableStyle();
483
+ }
484
+ }
485
+
486
+
487
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
488
+
489
+
490
+ // protected void checkBounds() {
491
+ // if (width == 0 || height == 0) {
492
+ // // calculate bounds here (also take kids into account)
493
+ // width = 1;
494
+ // height = 1;
495
+ // }
496
+ // }
497
+
498
+
499
+ /**
500
+ * Get the width of the drawing area (not necessarily the shape boundary).
501
+ */
502
+ public float getWidth() {
503
+ //checkBounds();
504
+ return width;
505
+ }
506
+
507
+
508
+ /**
509
+ * Get the height of the drawing area (not necessarily the shape boundary).
510
+ */
511
+ public float getHeight() {
512
+ //checkBounds();
513
+ return height;
514
+ }
515
+
516
+
517
+ /**
518
+ * Get the depth of the shape area (not necessarily the shape boundary). Only makes sense for 3D PShape subclasses,
519
+ * such as PShape3D.
520
+ */
521
+ public float getDepth() {
522
+ //checkBounds();
523
+ return depth;
524
+ }
525
+
526
+
527
+
528
+ /*
529
+ // TODO unapproved
530
+ protected PVector getTop() {
531
+ return getTop(null);
532
+ }
533
+
534
+
535
+ protected PVector getTop(PVector top) {
536
+ if (top == null) {
537
+ top = new PVector();
538
+ }
539
+ return top;
540
+ }
541
+
542
+
543
+ protected PVector getBottom() {
544
+ return getBottom(null);
545
+ }
546
+
547
+
548
+ protected PVector getBottom(PVector bottom) {
549
+ if (bottom == null) {
550
+ bottom = new PVector();
551
+ }
552
+ return bottom;
553
+ }
554
+ */
555
+
556
+
557
+ /**
558
+ * Return true if this shape is 2D. Defaults to true.
559
+ */
560
+ public boolean is2D() {
561
+ return !is3D;
562
+ }
563
+
564
+
565
+ /**
566
+ * Return true if this shape is 3D. Defaults to false.
567
+ */
568
+ public boolean is3D() {
569
+ return is3D;
570
+ }
571
+
572
+
573
+ public void set3D(boolean val) {
574
+ is3D = val;
575
+ }
576
+
577
+
578
+ // /**
579
+ // * Return true if this shape requires rendering through OpenGL. Defaults to false.
580
+ // */
581
+ // // TODO unapproved
582
+ // public boolean isGL() {
583
+ // return false;
584
+ // }
585
+
586
+
587
+ ///////////////////////////////////////////////////////////
588
+
589
+ //
590
+
591
+ // Drawing methods
592
+
593
+ public void textureMode(int mode) {
594
+ if (!openShape) {
595
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "textureMode()");
596
+ return;
597
+ }
598
+
599
+ textureMode = mode;
600
+ }
601
+
602
+ public void texture(PImage tex) {
603
+ if (!openShape) {
604
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "texture()");
605
+ return;
606
+ }
607
+
608
+ image = tex;
609
+ }
610
+
611
+ public void noTexture() {
612
+ if (!openShape) {
613
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "noTexture()");
614
+ return;
615
+ }
616
+
617
+ image = null;
618
+ }
619
+
620
+
621
+ // TODO unapproved
622
+ protected void solid(boolean solid) {
623
+ }
624
+
625
+
626
+ /**
627
+ * @webref shape:vertex
628
+ * @brief Starts a new contour
629
+ * @see PShape#endContour()
630
+ */
631
+ public void beginContour() {
632
+ if (!openShape) {
633
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "beginContour()");
634
+ return;
635
+ }
636
+
637
+ if (family == GROUP) {
638
+ PGraphics.showWarning("Cannot begin contour in GROUP shapes");
639
+ return;
640
+ }
641
+
642
+ if (openContour) {
643
+ PGraphics.showWarning("Already called beginContour().");
644
+ return;
645
+ }
646
+ openContour = true;
647
+ beginContourImpl();
648
+ }
649
+
650
+
651
+ protected void beginContourImpl() {
652
+ if (vertexCodes == null) {
653
+ vertexCodes = new int[10];
654
+ } else if (vertexCodes.length == vertexCodeCount) {
655
+ vertexCodes = PApplet.expand(vertexCodes);
656
+ }
657
+ vertexCodes[vertexCodeCount++] = BREAK;
658
+ }
659
+
660
+
661
+ /**
662
+ * @webref shape:vertex
663
+ * @brief Ends a contour
664
+ * @see PShape#beginContour()
665
+ */
666
+ public void endContour() {
667
+ if (!openShape) {
668
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "endContour()");
669
+ return;
670
+ }
671
+
672
+ if (family == GROUP) {
673
+ PGraphics.showWarning("Cannot end contour in GROUP shapes");
674
+ return;
675
+ }
676
+
677
+ if (!openContour) {
678
+ PGraphics.showWarning("Need to call beginContour() first.");
679
+ return;
680
+ }
681
+ endContourImpl();
682
+ openContour = false;
683
+ }
684
+
685
+
686
+ protected void endContourImpl() {
687
+ }
688
+
689
+
690
+ public void vertex(float x, float y) {
691
+ if (vertices == null) {
692
+ vertices = new float[10][2];
693
+ } else if (vertices.length == vertexCount) {
694
+ vertices = (float[][]) PApplet.expand(vertices);
695
+ }
696
+ vertices[vertexCount++] = new float[] { x, y };
697
+
698
+ if (vertexCodes == null) {
699
+ vertexCodes = new int[10];
700
+ } else if (vertexCodes.length == vertexCodeCount) {
701
+ vertexCodes = PApplet.expand(vertexCodes);
702
+ }
703
+ vertexCodes[vertexCodeCount++] = VERTEX;
704
+
705
+ if (x > width) {
706
+ width = x;
707
+ }
708
+ if (y > height) {
709
+ height = y;
710
+ }
711
+ }
712
+
713
+
714
+ public void vertex(float x, float y, float u, float v) {
715
+ }
716
+
717
+
718
+ public void vertex(float x, float y, float z) {
719
+ vertex(x, y); // maybe? maybe not?
720
+ }
721
+
722
+
723
+ public void vertex(float x, float y, float z, float u, float v) {
724
+ }
725
+
726
+
727
+ public void normal(float nx, float ny, float nz) {
728
+ }
729
+
730
+
731
+ public void attribPosition(String name, float x, float y, float z) {
732
+ }
733
+
734
+ public void attribNormal(String name, float nx, float ny, float nz) {
735
+ }
736
+
737
+
738
+ public void attribColor(String name, int color) {
739
+ }
740
+
741
+
742
+ public void attrib(String name, float... values) {
743
+ }
744
+
745
+
746
+ public void attrib(String name, int... values) {
747
+ }
748
+
749
+
750
+ public void attrib(String name, boolean... values) {
751
+ }
752
+
753
+
754
+ /**
755
+ * @webref pshape:method
756
+ * @brief Starts the creation of a new PShape
757
+ * @see PApplet#endShape()
758
+ */
759
+ public void beginShape() {
760
+ beginShape(POLYGON);
761
+ }
762
+
763
+
764
+ public void beginShape(int kind) {
765
+ this.kind = kind;
766
+ openShape = true;
767
+ }
768
+
769
+ /**
770
+ * @webref pshape:method
771
+ * @brief Finishes the creation of a new PShape
772
+ * @see PApplet#beginShape()
773
+ */
774
+ public void endShape() {
775
+ endShape(OPEN);
776
+ }
777
+
778
+
779
+ public void endShape(int mode) {
780
+ if (family == GROUP) {
781
+ PGraphics.showWarning("Cannot end GROUP shape");
782
+ return;
783
+ }
784
+
785
+ if (!openShape) {
786
+ PGraphics.showWarning("Need to call beginShape() first");
787
+ return;
788
+ }
789
+
790
+ close = (mode==CLOSE);
791
+
792
+ // this is the state of the shape
793
+ openShape = false;
794
+ }
795
+
796
+
797
+ //////////////////////////////////////////////////////////////
798
+
799
+ // STROKE CAP/JOIN/WEIGHT
800
+
801
+
802
+ public void strokeWeight(float weight) {
803
+ if (!openShape) {
804
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "strokeWeight()");
805
+ return;
806
+ }
807
+
808
+ strokeWeight = weight;
809
+ }
810
+
811
+ public void strokeJoin(int join) {
812
+ if (!openShape) {
813
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "strokeJoin()");
814
+ return;
815
+ }
816
+
817
+ strokeJoin = join;
818
+ }
819
+
820
+ public void strokeCap(int cap) {
821
+ if (!openShape) {
822
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "strokeCap()");
823
+ return;
824
+ }
825
+
826
+ strokeCap = cap;
827
+ }
828
+
829
+
830
+ //////////////////////////////////////////////////////////////
831
+
832
+ // FILL COLOR
833
+
834
+
835
+ public void noFill() {
836
+ if (!openShape) {
837
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "noFill()");
838
+ return;
839
+ }
840
+
841
+ fill = false;
842
+ fillColor = 0x0;
843
+
844
+ if (!setAmbient) {
845
+ ambientColor = fillColor;
846
+ }
847
+ }
848
+
849
+
850
+ public void fill(int rgb) {
851
+ if (!openShape) {
852
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
853
+ return;
854
+ }
855
+
856
+ fill = true;
857
+ colorCalc(rgb);
858
+ fillColor = calcColor;
859
+
860
+ if (!setAmbient) {
861
+ ambientColor = fillColor;
862
+ }
863
+ }
864
+
865
+
866
+ public void fill(int rgb, float alpha) {
867
+ if (!openShape) {
868
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
869
+ return;
870
+ }
871
+
872
+ fill = true;
873
+ colorCalc(rgb, alpha);
874
+ fillColor = calcColor;
875
+
876
+ if (!setAmbient) {
877
+ ambientColor = fillColor;
878
+ }
879
+ }
880
+
881
+
882
+ public void fill(float gray) {
883
+ if (!openShape) {
884
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
885
+ return;
886
+ }
887
+
888
+ fill = true;
889
+ colorCalc(gray);
890
+ fillColor = calcColor;
891
+
892
+ if (!setAmbient) {
893
+ ambientColor = fillColor;
894
+ }
895
+ }
896
+
897
+
898
+ public void fill(float gray, float alpha) {
899
+ if (!openShape) {
900
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
901
+ return;
902
+ }
903
+
904
+ fill = true;
905
+ colorCalc(gray, alpha);
906
+ fillColor = calcColor;
907
+
908
+ if (!setAmbient) {
909
+ ambient(fillColor);
910
+ setAmbient = false;
911
+ }
912
+
913
+ if (!setAmbient) {
914
+ ambientColor = fillColor;
915
+ }
916
+ }
917
+
918
+
919
+ public void fill(float x, float y, float z) {
920
+ if (!openShape) {
921
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
922
+ return;
923
+ }
924
+
925
+ fill = true;
926
+ colorCalc(x, y, z);
927
+ fillColor = calcColor;
928
+
929
+ if (!setAmbient) {
930
+ ambientColor = fillColor;
931
+ }
932
+ }
933
+
934
+
935
+ public void fill(float x, float y, float z, float a) {
936
+ if (!openShape) {
937
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "fill()");
938
+ return;
939
+ }
940
+
941
+ fill = true;
942
+ colorCalc(x, y, z, a);
943
+ fillColor = calcColor;
944
+
945
+ if (!setAmbient) {
946
+ ambientColor = fillColor;
947
+ }
948
+ }
949
+
950
+
951
+ //////////////////////////////////////////////////////////////
952
+
953
+ // STROKE COLOR
954
+
955
+
956
+ public void noStroke() {
957
+ if (!openShape) {
958
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "noStroke()");
959
+ return;
960
+ }
961
+
962
+ stroke = false;
963
+ }
964
+
965
+
966
+ public void stroke(int rgb) {
967
+ if (!openShape) {
968
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
969
+ return;
970
+ }
971
+
972
+ stroke = true;
973
+ colorCalc(rgb);
974
+ strokeColor = calcColor;
975
+ }
976
+
977
+
978
+ public void stroke(int rgb, float alpha) {
979
+ if (!openShape) {
980
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
981
+ return;
982
+ }
983
+
984
+ stroke = true;
985
+ colorCalc(rgb, alpha);
986
+ strokeColor = calcColor;
987
+ }
988
+
989
+
990
+ public void stroke(float gray) {
991
+ if (!openShape) {
992
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
993
+ return;
994
+ }
995
+
996
+ stroke = true;
997
+ colorCalc(gray);
998
+ strokeColor = calcColor;
999
+ }
1000
+
1001
+
1002
+ public void stroke(float gray, float alpha) {
1003
+ if (!openShape) {
1004
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
1005
+ return;
1006
+ }
1007
+
1008
+ stroke = true;
1009
+ colorCalc(gray, alpha);
1010
+ strokeColor = calcColor;
1011
+ }
1012
+
1013
+
1014
+ public void stroke(float x, float y, float z) {
1015
+ if (!openShape) {
1016
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
1017
+ return;
1018
+ }
1019
+
1020
+ stroke = true;
1021
+ colorCalc(x, y, z);
1022
+ strokeColor = calcColor;
1023
+ }
1024
+
1025
+
1026
+ public void stroke(float x, float y, float z, float alpha) {
1027
+ if (!openShape) {
1028
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "stroke()");
1029
+ return;
1030
+ }
1031
+
1032
+ stroke = true;
1033
+ colorCalc(x, y, z, alpha);
1034
+ strokeColor = calcColor;
1035
+ }
1036
+
1037
+
1038
+ //////////////////////////////////////////////////////////////
1039
+
1040
+ // TINT COLOR
1041
+
1042
+
1043
+ public void noTint() {
1044
+ if (!openShape) {
1045
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "noTint()");
1046
+ return;
1047
+ }
1048
+
1049
+ tint = false;
1050
+ }
1051
+
1052
+
1053
+ public void tint(int rgb) {
1054
+ if (!openShape) {
1055
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1056
+ return;
1057
+ }
1058
+
1059
+ tint = true;
1060
+ colorCalc(rgb);
1061
+ tintColor = calcColor;
1062
+ }
1063
+
1064
+
1065
+ public void tint(int rgb, float alpha) {
1066
+ if (!openShape) {
1067
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1068
+ return;
1069
+ }
1070
+
1071
+ tint = true;
1072
+ colorCalc(rgb, alpha);
1073
+ tintColor = calcColor;
1074
+ }
1075
+
1076
+
1077
+ public void tint(float gray) {
1078
+ if (!openShape) {
1079
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1080
+ return;
1081
+ }
1082
+
1083
+ tint = true;
1084
+ colorCalc(gray);
1085
+ tintColor = calcColor;
1086
+ }
1087
+
1088
+
1089
+ public void tint(float gray, float alpha) {
1090
+ if (!openShape) {
1091
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1092
+ return;
1093
+ }
1094
+
1095
+ tint = true;
1096
+ colorCalc(gray, alpha);
1097
+ tintColor = calcColor;
1098
+ }
1099
+
1100
+
1101
+ public void tint(float x, float y, float z) {
1102
+ if (!openShape) {
1103
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1104
+ return;
1105
+ }
1106
+
1107
+ tint = true;
1108
+ colorCalc(x, y, z);
1109
+ tintColor = calcColor;
1110
+ }
1111
+
1112
+
1113
+ public void tint(float x, float y, float z, float alpha) {
1114
+ if (!openShape) {
1115
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "tint()");
1116
+ return;
1117
+ }
1118
+
1119
+ tint = true;
1120
+ colorCalc(x, y, z, alpha);
1121
+ tintColor = calcColor;
1122
+ }
1123
+
1124
+
1125
+ //////////////////////////////////////////////////////////////
1126
+
1127
+ // Ambient set/update
1128
+
1129
+ public void ambient(int rgb) {
1130
+ if (!openShape) {
1131
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "ambient()");
1132
+ return;
1133
+ }
1134
+
1135
+ setAmbient = true;
1136
+ colorCalc(rgb);
1137
+ ambientColor = calcColor;
1138
+ }
1139
+
1140
+
1141
+ public void ambient(float gray) {
1142
+ if (!openShape) {
1143
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "ambient()");
1144
+ return;
1145
+ }
1146
+
1147
+ setAmbient = true;
1148
+ colorCalc(gray);
1149
+ ambientColor = calcColor;
1150
+ }
1151
+
1152
+
1153
+ public void ambient(float x, float y, float z) {
1154
+ if (!openShape) {
1155
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "ambient()");
1156
+ return;
1157
+ }
1158
+
1159
+ setAmbient = true;
1160
+ colorCalc(x, y, z);
1161
+ ambientColor = calcColor;
1162
+ }
1163
+
1164
+
1165
+ //////////////////////////////////////////////////////////////
1166
+
1167
+ // Specular set/update
1168
+
1169
+ public void specular(int rgb) {
1170
+ if (!openShape) {
1171
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "specular()");
1172
+ return;
1173
+ }
1174
+
1175
+ colorCalc(rgb);
1176
+ specularColor = calcColor;
1177
+ }
1178
+
1179
+
1180
+ public void specular(float gray) {
1181
+ if (!openShape) {
1182
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "specular()");
1183
+ return;
1184
+ }
1185
+
1186
+ colorCalc(gray);
1187
+ specularColor = calcColor;
1188
+ }
1189
+
1190
+
1191
+ public void specular(float x, float y, float z) {
1192
+ if (!openShape) {
1193
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "specular()");
1194
+ return;
1195
+ }
1196
+
1197
+ colorCalc(x, y, z);
1198
+ specularColor = calcColor;
1199
+ }
1200
+
1201
+
1202
+ //////////////////////////////////////////////////////////////
1203
+
1204
+ // Emissive set/update
1205
+
1206
+ public void emissive(int rgb) {
1207
+ if (!openShape) {
1208
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "emissive()");
1209
+ return;
1210
+ }
1211
+
1212
+ colorCalc(rgb);
1213
+ emissiveColor = calcColor;
1214
+ }
1215
+
1216
+
1217
+ public void emissive(float gray) {
1218
+ if (!openShape) {
1219
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "emissive()");
1220
+ return;
1221
+ }
1222
+
1223
+ colorCalc(gray);
1224
+ emissiveColor = calcColor;
1225
+ }
1226
+
1227
+
1228
+ public void emissive(float x, float y, float z) {
1229
+ if (!openShape) {
1230
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "emissive()");
1231
+ return;
1232
+ }
1233
+
1234
+ colorCalc(x, y, z);
1235
+ emissiveColor = calcColor;
1236
+ }
1237
+
1238
+
1239
+ //////////////////////////////////////////////////////////////
1240
+
1241
+ // Shininess set/update
1242
+
1243
+ public void shininess(float shine) {
1244
+ if (!openShape) {
1245
+ PGraphics.showWarning(OUTSIDE_BEGIN_END_ERROR, "shininess()");
1246
+ return;
1247
+ }
1248
+
1249
+ shininess = shine;
1250
+ }
1251
+
1252
+ ///////////////////////////////////////////////////////////
1253
+
1254
+ //
1255
+
1256
+ // Bezier curves
1257
+
1258
+
1259
+ public void bezierDetail(int detail) {
1260
+ }
1261
+
1262
+
1263
+ public void bezierVertex(float x2, float y2,
1264
+ float x3, float y3,
1265
+ float x4, float y4) {
1266
+ if (vertices == null) {
1267
+ vertices = new float[10][];
1268
+ } else if (vertexCount + 2 >= vertices.length) {
1269
+ vertices = (float[][]) PApplet.expand(vertices);
1270
+ }
1271
+ vertices[vertexCount++] = new float[] { x2, y2 };
1272
+ vertices[vertexCount++] = new float[] { x3, y3 };
1273
+ vertices[vertexCount++] = new float[] { x4, y4 };
1274
+
1275
+ // vertexCodes must be allocated because a vertex() call is required
1276
+ if (vertexCodes.length == vertexCodeCount) {
1277
+ vertexCodes = PApplet.expand(vertexCodes);
1278
+ }
1279
+ vertexCodes[vertexCodeCount++] = BEZIER_VERTEX;
1280
+
1281
+ if (x4 > width) {
1282
+ width = x4;
1283
+ }
1284
+ if (y4 > height) {
1285
+ height = y4;
1286
+ }
1287
+ }
1288
+
1289
+
1290
+ public void bezierVertex(float x2, float y2, float z2,
1291
+ float x3, float y3, float z3,
1292
+ float x4, float y4, float z4) {
1293
+ }
1294
+
1295
+
1296
+ public void quadraticVertex(float cx, float cy,
1297
+ float x3, float y3) {
1298
+ if (vertices == null) {
1299
+ vertices = new float[10][];
1300
+ } else if (vertexCount + 1 >= vertices.length) {
1301
+ vertices = (float[][]) PApplet.expand(vertices);
1302
+ }
1303
+ vertices[vertexCount++] = new float[] { cx, cy };
1304
+ vertices[vertexCount++] = new float[] { x3, y3 };
1305
+
1306
+ // vertexCodes must be allocated because a vertex() call is required
1307
+ if (vertexCodes.length == vertexCodeCount) {
1308
+ vertexCodes = PApplet.expand(vertexCodes);
1309
+ }
1310
+ vertexCodes[vertexCodeCount++] = QUADRATIC_VERTEX;
1311
+
1312
+ if (x3 > width) {
1313
+ width = x3;
1314
+ }
1315
+ if (y3 > height) {
1316
+ height = y3;
1317
+ }
1318
+ }
1319
+
1320
+
1321
+ public void quadraticVertex(float cx, float cy, float cz,
1322
+ float x3, float y3, float z3) {
1323
+ }
1324
+
1325
+
1326
+ ///////////////////////////////////////////////////////////
1327
+
1328
+ //
1329
+
1330
+ // Catmull-Rom curves
1331
+
1332
+ public void curveDetail(int detail) {
1333
+ }
1334
+
1335
+ public void curveTightness(float tightness) {
1336
+ }
1337
+
1338
+ public void curveVertex(float x, float y) {
1339
+ }
1340
+
1341
+ public void curveVertex(float x, float y, float z) {
1342
+ }
1343
+
1344
+
1345
+
1346
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1347
+
1348
+
1349
+ /*
1350
+ boolean strokeSaved;
1351
+ int strokeColorSaved;
1352
+ float strokeWeightSaved;
1353
+ int strokeCapSaved;
1354
+ int strokeJoinSaved;
1355
+
1356
+ boolean fillSaved;
1357
+ int fillColorSaved;
1358
+
1359
+ int rectModeSaved;
1360
+ int ellipseModeSaved;
1361
+ int shapeModeSaved;
1362
+ */
1363
+
1364
+
1365
+ protected void pre(PGraphics g) {
1366
+ if (matrix != null) {
1367
+ g.pushMatrix();
1368
+ g.applyMatrix(matrix);
1369
+ }
1370
+
1371
+ /*
1372
+ strokeSaved = g.stroke;
1373
+ strokeColorSaved = g.strokeColor;
1374
+ strokeWeightSaved = g.strokeWeight;
1375
+ strokeCapSaved = g.strokeCap;
1376
+ strokeJoinSaved = g.strokeJoin;
1377
+
1378
+ fillSaved = g.fill;
1379
+ fillColorSaved = g.fillColor;
1380
+
1381
+ rectModeSaved = g.rectMode;
1382
+ ellipseModeSaved = g.ellipseMode;
1383
+ shapeModeSaved = g.shapeMode;
1384
+ */
1385
+ if (style) {
1386
+ g.pushStyle();
1387
+ styles(g);
1388
+ }
1389
+ }
1390
+
1391
+
1392
+ protected void styles(PGraphics g) {
1393
+ // should not be necessary because using only the int version of color
1394
+ //parent.colorMode(PConstants.RGB, 255);
1395
+
1396
+ if (stroke) {
1397
+ g.stroke(strokeColor);
1398
+ g.strokeWeight(strokeWeight);
1399
+ g.strokeCap(strokeCap);
1400
+ g.strokeJoin(strokeJoin);
1401
+ } else {
1402
+ g.noStroke();
1403
+ }
1404
+
1405
+ if (fill) {
1406
+ //System.out.println("filling " + PApplet.hex(fillColor));
1407
+ g.fill(fillColor);
1408
+ } else {
1409
+ g.noFill();
1410
+ }
1411
+ }
1412
+
1413
+
1414
+ protected void post(PGraphics g) {
1415
+ // for (int i = 0; i < childCount; i++) {
1416
+ // children[i].draw(g);
1417
+ // }
1418
+
1419
+ /*
1420
+ // TODO this is not sufficient, since not saving fillR et al.
1421
+ g.stroke = strokeSaved;
1422
+ g.strokeColor = strokeColorSaved;
1423
+ g.strokeWeight = strokeWeightSaved;
1424
+ g.strokeCap = strokeCapSaved;
1425
+ g.strokeJoin = strokeJoinSaved;
1426
+
1427
+ g.fill = fillSaved;
1428
+ g.fillColor = fillColorSaved;
1429
+
1430
+ g.ellipseMode = ellipseModeSaved;
1431
+ */
1432
+
1433
+ if (matrix != null) {
1434
+ g.popMatrix();
1435
+ }
1436
+
1437
+ if (style) {
1438
+ g.popStyle();
1439
+ }
1440
+ }
1441
+
1442
+
1443
+ ////////////////////////////////////////////////////////////////////////
1444
+ //
1445
+ // Shape copy
1446
+
1447
+
1448
+ // TODO unapproved
1449
+ static protected PShape createShape(PApplet parent, PShape src) {
1450
+ PShape dest = null;
1451
+ if (src.family == GROUP) {
1452
+ dest = parent.createShape(GROUP);
1453
+ PShape.copyGroup(parent, src, dest);
1454
+ } else if (src.family == PRIMITIVE) {
1455
+ dest = parent.createShape(src.kind, src.params);
1456
+ PShape.copyPrimitive(src, dest);
1457
+ } else if (src.family == GEOMETRY) {
1458
+ dest = parent.createShape(src.kind);
1459
+ PShape.copyGeometry(src, dest);
1460
+ } else if (src.family == PATH) {
1461
+ dest = parent.createShape(PATH);
1462
+ PShape.copyPath(src, dest);
1463
+ }
1464
+ dest.setName(src.name);
1465
+ return dest;
1466
+ }
1467
+
1468
+
1469
+ // TODO unapproved
1470
+ static protected void copyGroup(PApplet parent, PShape src, PShape dest) {
1471
+ copyMatrix(src, dest);
1472
+ copyStyles(src, dest);
1473
+ copyImage(src, dest);
1474
+ for (int i = 0; i < src.childCount; i++) {
1475
+ PShape c = PShape.createShape(parent, src.children[i]);
1476
+ dest.addChild(c);
1477
+ }
1478
+ }
1479
+
1480
+
1481
+ // TODO unapproved
1482
+ static protected void copyPrimitive(PShape src, PShape dest) {
1483
+ copyMatrix(src, dest);
1484
+ copyStyles(src, dest);
1485
+ copyImage(src, dest);
1486
+ }
1487
+
1488
+
1489
+ // TODO unapproved
1490
+ static protected void copyGeometry(PShape src, PShape dest) {
1491
+ dest.beginShape(src.getKind());
1492
+
1493
+ copyMatrix(src, dest);
1494
+ copyStyles(src, dest);
1495
+ copyImage(src, dest);
1496
+
1497
+ if (src.style) {
1498
+ for (int i = 0; i < src.vertexCount; i++) {
1499
+ float[] vert = src.vertices[i];
1500
+
1501
+ dest.fill((int)(vert[PGraphics.A] * 255) << 24 |
1502
+ (int)(vert[PGraphics.R] * 255) << 16 |
1503
+ (int)(vert[PGraphics.G] * 255) << 8 |
1504
+ (int)(vert[PGraphics.B] * 255));
1505
+
1506
+ // Do we need to copy these as well?
1507
+ // dest.ambient(vert[PGraphics.AR] * 255, vert[PGraphics.AG] * 255, vert[PGraphics.AB] * 255);
1508
+ // dest.specular(vert[PGraphics.SPR] * 255, vert[PGraphics.SPG] * 255, vert[PGraphics.SPB] * 255);
1509
+ // dest.emissive(vert[PGraphics.ER] * 255, vert[PGraphics.EG] * 255, vert[PGraphics.EB] * 255);
1510
+ // dest.shininess(vert[PGraphics.SHINE]);
1511
+
1512
+ if (0 < PApplet.dist(vert[PGraphics.NX],
1513
+ vert[PGraphics.NY],
1514
+ vert[PGraphics.NZ], 0, 0, 0)) {
1515
+ dest.normal(vert[PGraphics.NX],
1516
+ vert[PGraphics.NY],
1517
+ vert[PGraphics.NZ]);
1518
+ }
1519
+ dest.vertex(vert[X], vert[Y], vert[Z],
1520
+ vert[PGraphics.U],
1521
+ vert[PGraphics.V]);
1522
+ }
1523
+ } else {
1524
+ for (int i = 0; i < src.vertexCount; i++) {
1525
+ float[] vert = src.vertices[i];
1526
+ if (vert[Z] == 0) {
1527
+ dest.vertex(vert[X], vert[Y]);
1528
+ } else {
1529
+ dest.vertex(vert[X], vert[Y], vert[Z]);
1530
+ }
1531
+ }
1532
+ }
1533
+
1534
+ dest.endShape();
1535
+ }
1536
+
1537
+
1538
+ // TODO unapproved
1539
+ static protected void copyPath(PShape src, PShape dest) {
1540
+ copyMatrix(src, dest);
1541
+ copyStyles(src, dest);
1542
+ copyImage(src, dest);
1543
+ dest.close = src.close;
1544
+ dest.setPath(src.vertexCount, src.vertices, src.vertexCodeCount, src.vertexCodes);
1545
+ }
1546
+
1547
+
1548
+ // TODO unapproved
1549
+ static protected void copyMatrix(PShape src, PShape dest) {
1550
+ if (src.matrix != null) {
1551
+ dest.applyMatrix(src.matrix);
1552
+ }
1553
+ }
1554
+
1555
+
1556
+ // TODO unapproved
1557
+ static protected void copyStyles(PShape src, PShape dest) {
1558
+ dest.ellipseMode = src.ellipseMode;
1559
+ dest.rectMode = src.rectMode;
1560
+
1561
+ if (src.stroke) {
1562
+ dest.stroke = true;
1563
+ dest.strokeColor = src.strokeColor;
1564
+ dest.strokeWeight = src.strokeWeight;
1565
+ dest.strokeCap = src.strokeCap;
1566
+ dest.strokeJoin = src.strokeJoin;
1567
+ } else {
1568
+ dest.stroke = false;
1569
+ }
1570
+
1571
+ if (src.fill) {
1572
+ dest.fill = true;
1573
+ dest.fillColor = src.fillColor;
1574
+ } else {
1575
+ dest.fill = false;
1576
+ }
1577
+ }
1578
+
1579
+
1580
+ // TODO unapproved
1581
+ static protected void copyImage(PShape src, PShape dest) {
1582
+ if (src.image != null) {
1583
+ dest.texture(src.image);
1584
+ }
1585
+ }
1586
+
1587
+
1588
+
1589
+ ////////////////////////////////////////////////////////////////////////
1590
+
1591
+
1592
+ /**
1593
+ * Called by the following (the shape() command adds the g)
1594
+ * PShape s = loadShape("blah.svg");
1595
+ * shape(s);
1596
+ */
1597
+ public void draw(PGraphics g) {
1598
+ if (visible) {
1599
+ pre(g);
1600
+ drawImpl(g);
1601
+ post(g);
1602
+ }
1603
+ }
1604
+
1605
+
1606
+ /**
1607
+ * Draws the SVG document.
1608
+ */
1609
+ protected void drawImpl(PGraphics g) {
1610
+ if (family == GROUP) {
1611
+ drawGroup(g);
1612
+ } else if (family == PRIMITIVE) {
1613
+ drawPrimitive(g);
1614
+ } else if (family == GEOMETRY) {
1615
+ // Not same as path: `kind` matters.
1616
+ // drawPath(g);
1617
+ drawGeometry(g);
1618
+ } else if (family == PATH) {
1619
+ drawPath(g);
1620
+ }
1621
+ }
1622
+
1623
+
1624
+ protected void drawGroup(PGraphics g) {
1625
+ for (int i = 0; i < childCount; i++) {
1626
+ children[i].draw(g);
1627
+ }
1628
+ }
1629
+
1630
+
1631
+ protected void drawPrimitive(PGraphics g) {
1632
+ if (kind == POINT) {
1633
+ g.point(params[0], params[1]);
1634
+
1635
+ } else if (kind == LINE) {
1636
+ if (params.length == 4) { // 2D
1637
+ g.line(params[0], params[1],
1638
+ params[2], params[3]);
1639
+ } else { // 3D
1640
+ g.line(params[0], params[1], params[2],
1641
+ params[3], params[4], params[5]);
1642
+ }
1643
+
1644
+ } else if (kind == TRIANGLE) {
1645
+ g.triangle(params[0], params[1],
1646
+ params[2], params[3],
1647
+ params[4], params[5]);
1648
+
1649
+ } else if (kind == QUAD) {
1650
+ g.quad(params[0], params[1],
1651
+ params[2], params[3],
1652
+ params[4], params[5],
1653
+ params[6], params[7]);
1654
+
1655
+ } else if (kind == RECT) {
1656
+
1657
+ if (imagePath != null){
1658
+ loadImage(g);
1659
+ }
1660
+ if (image != null) {
1661
+ int oldMode = g.imageMode;
1662
+ g.imageMode(CORNER);
1663
+ g.image(image, params[0], params[1], params[2], params[3]);
1664
+ g.imageMode(oldMode);
1665
+ } else {
1666
+ int oldMode = g.rectMode;
1667
+ g.rectMode(rectMode);
1668
+ if (params.length == 4) {
1669
+ g.rect(params[0], params[1],
1670
+ params[2], params[3]);
1671
+ } else if (params.length == 5) {
1672
+ g.rect(params[0], params[1],
1673
+ params[2], params[3],
1674
+ params[4]);
1675
+ } else if (params.length == 8) {
1676
+ g.rect(params[0], params[1],
1677
+ params[2], params[3],
1678
+ params[4], params[5],
1679
+ params[6], params[7]);
1680
+ }
1681
+ g.rectMode(oldMode);
1682
+ }
1683
+ } else if (kind == ELLIPSE) {
1684
+ int oldMode = g.ellipseMode;
1685
+ g.ellipseMode(ellipseMode);
1686
+ g.ellipse(params[0], params[1],
1687
+ params[2], params[3]);
1688
+ g.ellipseMode(oldMode);
1689
+
1690
+ } else if (kind == ARC) {
1691
+ int oldMode = g.ellipseMode;
1692
+ g.ellipseMode(ellipseMode);
1693
+ if (params.length == 6) {
1694
+ g.arc(params[0], params[1],
1695
+ params[2], params[3],
1696
+ params[4], params[5]);
1697
+ } else if (params.length == 7) {
1698
+ g.arc(params[0], params[1],
1699
+ params[2], params[3],
1700
+ params[4], params[5],
1701
+ (int) params[6]);
1702
+ }
1703
+ g.ellipseMode(oldMode);
1704
+
1705
+ } else if (kind == BOX) {
1706
+ if (params.length == 1) {
1707
+ g.box(params[0]);
1708
+ } else {
1709
+ g.box(params[0], params[1], params[2]);
1710
+ }
1711
+
1712
+ } else if (kind == SPHERE) {
1713
+ g.sphere(params[0]);
1714
+ }
1715
+ }
1716
+
1717
+
1718
+ protected void drawGeometry(PGraphics g) {
1719
+ // get cache object using g.
1720
+ g.beginShape(kind);
1721
+ if (style) {
1722
+ for (int i = 0; i < vertexCount; i++) {
1723
+ g.vertex(vertices[i]);
1724
+ }
1725
+ } else {
1726
+ for (int i = 0; i < vertexCount; i++) {
1727
+ float[] vert = vertices[i];
1728
+ if (vert[Z] == 0) {
1729
+ g.vertex(vert[X], vert[Y]);
1730
+ } else {
1731
+ g.vertex(vert[X], vert[Y], vert[Z]);
1732
+ }
1733
+ }
1734
+ }
1735
+ g.endShape(close ? CLOSE : OPEN);
1736
+ }
1737
+
1738
+
1739
+ /*
1740
+ protected void drawPath(PGraphics g) {
1741
+ g.beginShape();
1742
+ for (int j = 0; j < childCount; j++) {
1743
+ if (j > 0) g.breakShape();
1744
+ int count = children[j].vertexCount;
1745
+ float[][] vert = children[j].vertices;
1746
+ int[] code = children[j].vertexCodes;
1747
+
1748
+ for (int i = 0; i < count; i++) {
1749
+ if (style) {
1750
+ if (children[j].fill) {
1751
+ g.fill(vert[i][R], vert[i][G], vert[i][B]);
1752
+ } else {
1753
+ g.noFill();
1754
+ }
1755
+ if (children[j].stroke) {
1756
+ g.stroke(vert[i][R], vert[i][G], vert[i][B]);
1757
+ } else {
1758
+ g.noStroke();
1759
+ }
1760
+ }
1761
+ g.edge(vert[i][EDGE] == 1);
1762
+
1763
+ if (code[i] == VERTEX) {
1764
+ g.vertex(vert[i]);
1765
+
1766
+ } else if (code[i] == BEZIER_VERTEX) {
1767
+ float z0 = vert[i+0][Z];
1768
+ float z1 = vert[i+1][Z];
1769
+ float z2 = vert[i+2][Z];
1770
+ if (z0 == 0 && z1 == 0 && z2 == 0) {
1771
+ g.bezierVertex(vert[i+0][X], vert[i+0][Y], z0,
1772
+ vert[i+1][X], vert[i+1][Y], z1,
1773
+ vert[i+2][X], vert[i+2][Y], z2);
1774
+ } else {
1775
+ g.bezierVertex(vert[i+0][X], vert[i+0][Y],
1776
+ vert[i+1][X], vert[i+1][Y],
1777
+ vert[i+2][X], vert[i+2][Y]);
1778
+ }
1779
+ } else if (code[i] == CURVE_VERTEX) {
1780
+ float z = vert[i][Z];
1781
+ if (z == 0) {
1782
+ g.curveVertex(vert[i][X], vert[i][Y]);
1783
+ } else {
1784
+ g.curveVertex(vert[i][X], vert[i][Y], z);
1785
+ }
1786
+ }
1787
+ }
1788
+ }
1789
+ g.endShape();
1790
+ }
1791
+ */
1792
+
1793
+ protected void drawPath(PGraphics g) {
1794
+ // Paths might be empty (go figure)
1795
+ // http://dev.processing.org/bugs/show_bug.cgi?id=982
1796
+ if (vertices == null) return;
1797
+
1798
+ boolean insideContour = false;
1799
+ g.beginShape();
1800
+
1801
+ if (vertexCodeCount == 0) { // each point is a simple vertex
1802
+ if (vertices[0].length == 2) { // drawing 2D vertices
1803
+ for (int i = 0; i < vertexCount; i++) {
1804
+ g.vertex(vertices[i][X], vertices[i][Y]);
1805
+ }
1806
+ } else { // drawing 3D vertices
1807
+ for (int i = 0; i < vertexCount; i++) {
1808
+ g.vertex(vertices[i][X], vertices[i][Y], vertices[i][Z]);
1809
+ }
1810
+ }
1811
+
1812
+ } else { // coded set of vertices
1813
+ int index = 0;
1814
+
1815
+ if (vertices[0].length == 2) { // drawing a 2D path
1816
+ for (int j = 0; j < vertexCodeCount; j++) {
1817
+ switch (vertexCodes[j]) {
1818
+
1819
+ case VERTEX:
1820
+ g.vertex(vertices[index][X], vertices[index][Y]);
1821
+ index++;
1822
+ break;
1823
+
1824
+ case QUADRATIC_VERTEX:
1825
+ g.quadraticVertex(vertices[index+0][X], vertices[index+0][Y],
1826
+ vertices[index+1][X], vertices[index+1][Y]);
1827
+ index += 2;
1828
+ break;
1829
+
1830
+ case BEZIER_VERTEX:
1831
+ g.bezierVertex(vertices[index+0][X], vertices[index+0][Y],
1832
+ vertices[index+1][X], vertices[index+1][Y],
1833
+ vertices[index+2][X], vertices[index+2][Y]);
1834
+ index += 3;
1835
+ break;
1836
+
1837
+ case CURVE_VERTEX:
1838
+ g.curveVertex(vertices[index][X], vertices[index][Y]);
1839
+ index++;
1840
+ break;
1841
+
1842
+ case BREAK:
1843
+ if (insideContour) {
1844
+ g.endContour();
1845
+ }
1846
+ g.beginContour();
1847
+ insideContour = true;
1848
+ }
1849
+ }
1850
+ } else { // drawing a 3D path
1851
+ for (int j = 0; j < vertexCodeCount; j++) {
1852
+ switch (vertexCodes[j]) {
1853
+
1854
+ case VERTEX:
1855
+ g.vertex(vertices[index][X], vertices[index][Y], vertices[index][Z]);
1856
+ index++;
1857
+ break;
1858
+
1859
+ case QUADRATIC_VERTEX:
1860
+ g.quadraticVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z],
1861
+ vertices[index+1][X], vertices[index+1][Y], vertices[index+0][Z]);
1862
+ index += 2;
1863
+ break;
1864
+
1865
+
1866
+ case BEZIER_VERTEX:
1867
+ g.bezierVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z],
1868
+ vertices[index+1][X], vertices[index+1][Y], vertices[index+1][Z],
1869
+ vertices[index+2][X], vertices[index+2][Y], vertices[index+2][Z]);
1870
+ index += 3;
1871
+ break;
1872
+
1873
+ case CURVE_VERTEX:
1874
+ g.curveVertex(vertices[index][X], vertices[index][Y], vertices[index][Z]);
1875
+ index++;
1876
+ break;
1877
+
1878
+ case BREAK:
1879
+ if (insideContour) {
1880
+ g.endContour();
1881
+ }
1882
+ g.beginContour();
1883
+ insideContour = true;
1884
+ }
1885
+ }
1886
+ }
1887
+ }
1888
+ if (insideContour) {
1889
+ g.endContour();
1890
+ }
1891
+ g.endShape(close ? CLOSE : OPEN);
1892
+ }
1893
+
1894
+ private void loadImage(PGraphics g){
1895
+
1896
+ if(this.imagePath.startsWith("data:image")){
1897
+ loadBase64Image();
1898
+ }
1899
+
1900
+ if(this.imagePath.startsWith("file://")){
1901
+ loadFileSystemImage(g);
1902
+ }
1903
+ this.imagePath = null;
1904
+ }
1905
+
1906
+ private void loadFileSystemImage(PGraphics g){
1907
+ imagePath = imagePath.substring(7);
1908
+ PImage loadedImage = g.parent.loadImage(imagePath);
1909
+ if(loadedImage == null){
1910
+ System.err.println("Error loading image file: " + imagePath);
1911
+ }else{
1912
+ setTexture(loadedImage);
1913
+ }
1914
+ }
1915
+
1916
+ private void loadBase64Image() {
1917
+ PImage loadedImage = parseBase64Image(this.imagePath);
1918
+ if (loadedImage != null) {
1919
+ setTexture(loadedImage);
1920
+ }
1921
+ }
1922
+
1923
+ /**
1924
+ * Parse a base 64 encoded image within an image path.
1925
+ *
1926
+ * @param imagePath The image path containing the base 64 image data.
1927
+ * @return Newly loaded PImage.
1928
+ */
1929
+ protected static PImage parseBase64Image(String imagePath) {
1930
+ String[] parts = imagePath.split(";base64,");
1931
+ String extension = parts[0].substring(11);
1932
+ String encodedData = parts[1];
1933
+
1934
+ byte[] decodedBytes = Base64.getDecoder().decode(encodedData);
1935
+
1936
+ if(decodedBytes == null){
1937
+ System.err.println("Decode Error on image: " + imagePath.substring(0, 20));
1938
+ return null;
1939
+ }
1940
+
1941
+ Image awtImage = new ImageIcon(decodedBytes).getImage();
1942
+
1943
+ if (awtImage instanceof BufferedImage) {
1944
+ BufferedImage buffImage = (BufferedImage) awtImage;
1945
+ int space = buffImage.getColorModel().getColorSpace().getType();
1946
+ if (space == ColorSpace.TYPE_CMYK) {
1947
+ System.err.println("Could not load CMYK color space on image: " + imagePath.substring(0, 20));
1948
+ return null;
1949
+ }
1950
+ }
1951
+
1952
+ // if it's a .gif image, test to see if it has transparency
1953
+ boolean requiresCheckAlpha = extension.equals("gif") || extension.equals("png") ||
1954
+ extension.equals("unknown");
1955
+
1956
+ PImage loadedImage = new PImageAWT(awtImage);
1957
+
1958
+ if (requiresCheckAlpha) {
1959
+ loadedImage.checkAlpha();
1960
+ }
1961
+
1962
+ if (loadedImage.width == -1) {
1963
+ // error...
1964
+ }
1965
+
1966
+ return loadedImage;
1967
+ }
1968
+
1969
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1970
+
1971
+
1972
+ public PShape getParent() {
1973
+ return parent;
1974
+ }
1975
+
1976
+ /**
1977
+ * @webref
1978
+ * @brief Returns the number of children
1979
+ */
1980
+ public int getChildCount() {
1981
+ return childCount;
1982
+ }
1983
+
1984
+
1985
+ /** Resize the children[] array to be in line with childCount */
1986
+ protected void crop() {
1987
+ // https://github.com/processing/processing/issues/3347
1988
+ if (children.length != childCount) {
1989
+ children = (PShape[]) PApplet.subset(children, 0, childCount);
1990
+ }
1991
+ }
1992
+
1993
+
1994
+ public PShape[] getChildren() {
1995
+ crop();
1996
+ return children;
1997
+ }
1998
+
1999
+ /**
2000
+ * ( begin auto-generated from PShape_getChild.xml )
2001
+ *
2002
+ * Extracts a child shape from a parent shape. Specify the name of the
2003
+ * shape with the <b>target</b> parameter. The shape is returned as a
2004
+ * <b>PShape</b> object, or <b>null</b> is returned if there is an error.
2005
+ *
2006
+ * ( end auto-generated )
2007
+ * @webref pshape:method
2008
+ * @usage web_application
2009
+ * @brief Returns a child element of a shape as a PShape object
2010
+ * @param index the layer position of the shape to get
2011
+ * @see PShape#addChild(PShape)
2012
+ */
2013
+ public PShape getChild(int index) {
2014
+ crop();
2015
+ return children[index];
2016
+ }
2017
+
2018
+ /**
2019
+ * @param target the name of the shape to get
2020
+ */
2021
+ public PShape getChild(String target) {
2022
+ if (name != null && name.equals(target)) {
2023
+ return this;
2024
+ }
2025
+ if (nameTable != null) {
2026
+ PShape found = nameTable.get(target);
2027
+ if (found != null) return found;
2028
+ }
2029
+ for (int i = 0; i < childCount; i++) {
2030
+ PShape found = children[i].getChild(target);
2031
+ if (found != null) return found;
2032
+ }
2033
+ return null;
2034
+ }
2035
+
2036
+
2037
+ /**
2038
+ * Same as getChild(name), except that it first walks all the way up the
2039
+ * hierarchy to the eldest grandparent, so that children can be found anywhere.
2040
+ * @param target
2041
+ * @return
2042
+ */
2043
+ public PShape findChild(String target) {
2044
+ if (parent == null) {
2045
+ return getChild(target);
2046
+
2047
+ } else {
2048
+ return parent.findChild(target);
2049
+ }
2050
+ }
2051
+
2052
+
2053
+ // can't be just 'add' because that suggests additive geometry
2054
+ /**
2055
+ * @webref pshape:method
2056
+ * @brief Adds a new child
2057
+ * @param who any variable of type PShape
2058
+ * @see PShape#getChild(int)
2059
+ */
2060
+ public void addChild(PShape who) {
2061
+ if (children == null) {
2062
+ children = new PShape[1];
2063
+ }
2064
+ if (childCount == children.length) {
2065
+ children = (PShape[]) PApplet.expand(children);
2066
+ }
2067
+ children[childCount++] = who;
2068
+ who.parent = this;
2069
+
2070
+ if (who.getName() != null) {
2071
+ addName(who.getName(), who);
2072
+ }
2073
+ }
2074
+
2075
+
2076
+ // adds child who exactly at position idx in the array of children.
2077
+ /**
2078
+ * @param idx the layer position in which to insert the new child
2079
+ */
2080
+ public void addChild(PShape who, int idx) {
2081
+ if (idx < childCount) {
2082
+ if (childCount == children.length) {
2083
+ children = (PShape[]) PApplet.expand(children);
2084
+ }
2085
+
2086
+ // Copy [idx, childCount - 1] to [idx + 1, childCount]
2087
+ for (int i = childCount - 1; i >= idx; i--) {
2088
+ children[i + 1] = children[i];
2089
+ }
2090
+ childCount++;
2091
+
2092
+ children[idx] = who;
2093
+
2094
+ who.parent = this;
2095
+
2096
+ if (who.getName() != null) {
2097
+ addName(who.getName(), who);
2098
+ }
2099
+ }
2100
+ }
2101
+
2102
+
2103
+ /**
2104
+ * Remove the child shape with index idx.
2105
+ * @param idx
2106
+ */
2107
+ public void removeChild(int idx) {
2108
+ if (idx < childCount) {
2109
+ PShape child = children[idx];
2110
+
2111
+ // Copy [idx + 1, childCount - 1] to [idx, childCount - 2]
2112
+ for (int i = idx; i < childCount - 1; i++) {
2113
+ children[i] = children[i + 1];
2114
+ }
2115
+ childCount--;
2116
+
2117
+ if (child.getName() != null && nameTable != null) {
2118
+ nameTable.remove(child.getName());
2119
+ }
2120
+ }
2121
+ }
2122
+
2123
+
2124
+ /**
2125
+ * Add a shape to the name lookup table.
2126
+ */
2127
+ public void addName(String nom, PShape shape) {
2128
+ if (parent != null) {
2129
+ parent.addName(nom, shape);
2130
+ } else {
2131
+ if (nameTable == null) {
2132
+ nameTable = new HashMap<>();
2133
+ }
2134
+ nameTable.put(nom, shape);
2135
+ }
2136
+ }
2137
+
2138
+
2139
+ /**
2140
+ * Returns the index of child who.
2141
+ */
2142
+ public int getChildIndex(PShape who) {
2143
+ for (int i = 0; i < childCount; i++) {
2144
+ if (children[i] == who) {
2145
+ return i;
2146
+ }
2147
+ }
2148
+ return -1;
2149
+ }
2150
+
2151
+
2152
+ public PShape getTessellation() {
2153
+ return null;
2154
+ }
2155
+
2156
+
2157
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2158
+
2159
+
2160
+ /** The shape type, one of GROUP, PRIMITIVE, PATH, or GEOMETRY.
2161
+ * @return */
2162
+ public int getFamily() {
2163
+ return family;
2164
+ }
2165
+
2166
+
2167
+ public int getKind() {
2168
+ return kind;
2169
+ }
2170
+
2171
+
2172
+ public float[] getParams() {
2173
+ return getParams(null);
2174
+ }
2175
+
2176
+
2177
+ public float[] getParams(float[] target) {
2178
+ if (target == null || target.length != params.length) {
2179
+ target = new float[params.length];
2180
+ }
2181
+ PApplet.arrayCopy(params, target);
2182
+ return target;
2183
+ }
2184
+
2185
+
2186
+ public float getParam(int index) {
2187
+ return params[index];
2188
+ }
2189
+
2190
+
2191
+ protected void setParams(float[] source) {
2192
+ if (params == null) {
2193
+ params = new float[source.length];
2194
+ }
2195
+ if (source.length != params.length) {
2196
+ PGraphics.showWarning("Wrong number of parameters");
2197
+ return;
2198
+ }
2199
+ PApplet.arrayCopy(source, params);
2200
+ }
2201
+
2202
+
2203
+ public void setPath(int vcount, float[][] verts) {
2204
+ setPath(vcount, verts, 0, null);
2205
+ }
2206
+
2207
+
2208
+ protected void setPath(int vcount, float[][] verts, int ccount, int[] codes) {
2209
+ if (verts == null || verts.length < vcount) return;
2210
+ if (0 < ccount && (codes == null || codes.length < ccount)) return;
2211
+
2212
+ int ndim = verts[0].length;
2213
+ vertexCount = vcount;
2214
+ vertices = new float[vertexCount][ndim];
2215
+ for (int i = 0; i < vertexCount; i++) {
2216
+ PApplet.arrayCopy(verts[i], vertices[i]);
2217
+ }
2218
+
2219
+ vertexCodeCount = ccount;
2220
+ if (0 < vertexCodeCount) {
2221
+ vertexCodes = new int[vertexCodeCount];
2222
+ PApplet.arrayCopy(codes, vertexCodes, vertexCodeCount);
2223
+ }
2224
+ }
2225
+
2226
+ /**
2227
+ * @webref pshape:method
2228
+ * @brief Returns the total number of vertices as an int
2229
+ * @see PShape#getVertex(int)
2230
+ * @see PShape#setVertex(int, float, float)
2231
+ */
2232
+ public int getVertexCount() {
2233
+ if (family == GROUP || family == PRIMITIVE) {
2234
+ PGraphics.showWarning(NO_VERTICES_ERROR);
2235
+ }
2236
+ return vertexCount;
2237
+ }
2238
+
2239
+
2240
+ /**
2241
+ * @webref pshape:method
2242
+ * @brief Returns the vertex at the index position
2243
+ * @param index the location of the vertex
2244
+ * @see PShape#setVertex(int, float, float)
2245
+ * @see PShape#getVertexCount()
2246
+ */
2247
+ public PVector getVertex(int index) {
2248
+ return getVertex(index, null);
2249
+ }
2250
+
2251
+
2252
+ /**
2253
+ * @param vec PVector to assign the data to
2254
+ */
2255
+ public PVector getVertex(int index, PVector vec) {
2256
+ if (vec == null) {
2257
+ vec = new PVector();
2258
+ }
2259
+ float[] vert = vertices[index];
2260
+ vec.x = vert[X];
2261
+ vec.y = vert[Y];
2262
+ if (vert.length > 2) {
2263
+ vec.z = vert[Z];
2264
+ } else {
2265
+ vec.z = 0; // in case this isn't a new vector
2266
+ }
2267
+ return vec;
2268
+ }
2269
+
2270
+
2271
+ public float getVertexX(int index) {
2272
+ return vertices[index][X];
2273
+ }
2274
+
2275
+
2276
+ public float getVertexY(int index) {
2277
+ return vertices[index][Y];
2278
+ }
2279
+
2280
+
2281
+ public float getVertexZ(int index) {
2282
+ return vertices[index][Z];
2283
+ }
2284
+
2285
+
2286
+ /**
2287
+ * @webref pshape:method
2288
+ * @brief Sets the vertex at the index position
2289
+ * @param index the location of the vertex
2290
+ * @param x the x value for the vertex
2291
+ * @param y the y value for the vertex
2292
+ * @see PShape#getVertex(int)
2293
+ * @see PShape#getVertexCount()
2294
+ */
2295
+ public void setVertex(int index, float x, float y) {
2296
+ if (openShape) {
2297
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setVertex()");
2298
+ return;
2299
+ }
2300
+
2301
+ vertices[index][X] = x;
2302
+ vertices[index][Y] = y;
2303
+ }
2304
+
2305
+
2306
+ /**
2307
+ * @param z the z value for the vertex
2308
+ */
2309
+ public void setVertex(int index, float x, float y, float z) {
2310
+ if (openShape) {
2311
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setVertex()");
2312
+ return;
2313
+ }
2314
+
2315
+ vertices[index][X] = x;
2316
+ vertices[index][Y] = y;
2317
+ vertices[index][Z] = z;
2318
+ }
2319
+
2320
+
2321
+ /**
2322
+ * @param vec the PVector to define the x, y, z coordinates
2323
+ */
2324
+ public void setVertex(int index, PVector vec) {
2325
+ if (openShape) {
2326
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setVertex()");
2327
+ return;
2328
+ }
2329
+
2330
+ vertices[index][X] = vec.x;
2331
+ vertices[index][Y] = vec.y;
2332
+
2333
+ if (vertices[index].length > 2) {
2334
+ vertices[index][Z] = vec.z;
2335
+ } else if (vec.z != 0 && vec.z == vec.z) {
2336
+ throw new IllegalArgumentException("Cannot set a z-coordinate on a 2D shape");
2337
+ }
2338
+ }
2339
+
2340
+
2341
+ public PVector getNormal(int index) {
2342
+ return getNormal(index, null);
2343
+ }
2344
+
2345
+
2346
+ public PVector getNormal(int index, PVector vec) {
2347
+ if (vec == null) {
2348
+ vec = new PVector();
2349
+ }
2350
+ vec.x = vertices[index][PGraphics.NX];
2351
+ vec.y = vertices[index][PGraphics.NY];
2352
+ vec.z = vertices[index][PGraphics.NZ];
2353
+ return vec;
2354
+ }
2355
+
2356
+
2357
+ public float getNormalX(int index) {
2358
+ return vertices[index][PGraphics.NX];
2359
+ }
2360
+
2361
+
2362
+ public float getNormalY(int index) {
2363
+ return vertices[index][PGraphics.NY];
2364
+ }
2365
+
2366
+
2367
+ public float getNormalZ(int index) {
2368
+ return vertices[index][PGraphics.NZ];
2369
+ }
2370
+
2371
+
2372
+ public void setNormal(int index, float nx, float ny, float nz) {
2373
+ if (openShape) {
2374
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setNormal()");
2375
+ return;
2376
+ }
2377
+
2378
+ vertices[index][PGraphics.NX] = nx;
2379
+ vertices[index][PGraphics.NY] = ny;
2380
+ vertices[index][PGraphics.NZ] = nz;
2381
+ }
2382
+
2383
+
2384
+
2385
+ public void setAttrib(String name, int index, float... values) {
2386
+ }
2387
+
2388
+
2389
+ public void setAttrib(String name, int index, int... values) {
2390
+ }
2391
+
2392
+
2393
+ public void setAttrib(String name, int index, boolean... values) {
2394
+ }
2395
+
2396
+
2397
+ public float getTextureU(int index) {
2398
+ return vertices[index][PGraphics.U];
2399
+ }
2400
+
2401
+
2402
+ public float getTextureV(int index) {
2403
+ return vertices[index][PGraphics.V];
2404
+ }
2405
+
2406
+
2407
+ public void setTextureUV(int index, float u, float v) {
2408
+ if (openShape) {
2409
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTextureUV()");
2410
+ return;
2411
+ }
2412
+
2413
+ // make sure we allocated the vertices array and that vertex exists
2414
+ if (vertices == null ||
2415
+ index >= vertices.length) {
2416
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setTextureUV()");
2417
+ return;
2418
+ }
2419
+
2420
+
2421
+ vertices[index][PGraphics.U] = u;
2422
+ vertices[index][PGraphics.V] = v;
2423
+ }
2424
+
2425
+
2426
+ public void setTextureMode(int mode) {
2427
+ if (openShape) {
2428
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTextureMode()");
2429
+ return;
2430
+ }
2431
+
2432
+ textureMode = mode;
2433
+ }
2434
+
2435
+
2436
+ public void setTexture(PImage tex) {
2437
+ if (openShape) {
2438
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTexture()");
2439
+ return;
2440
+ }
2441
+
2442
+ image = tex;
2443
+ }
2444
+
2445
+
2446
+ public int getFill(int index) {
2447
+ // make sure we allocated the vertices array and that vertex exists
2448
+ if (vertices == null ||
2449
+ index >= vertices.length) {
2450
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getFill()");
2451
+ return fillColor;
2452
+ }
2453
+
2454
+ if (image == null) {
2455
+ int a = (int) (vertices[index][PGraphics.A] * 255);
2456
+ int r = (int) (vertices[index][PGraphics.R] * 255);
2457
+ int g = (int) (vertices[index][PGraphics.G] * 255);
2458
+ int b = (int) (vertices[index][PGraphics.B] * 255);
2459
+ return (a << 24) | (r << 16) | (g << 8) | b;
2460
+ } else {
2461
+ return 0;
2462
+ }
2463
+ }
2464
+
2465
+ /**
2466
+ * @nowebref
2467
+ */
2468
+ public void setFill(boolean fill) {
2469
+ if (openShape) {
2470
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setFill()");
2471
+ return;
2472
+ }
2473
+
2474
+ this.fill = fill;
2475
+ }
2476
+
2477
+ /**
2478
+ * ( begin auto-generated from PShape_setFill.xml )
2479
+ *
2480
+ * The <b>setFill()</b> method defines the fill color of a <b>PShape</b>.
2481
+ * This method is used after shapes are created or when a shape is defined explicitly
2482
+ * (e.g. <b>createShape(RECT, 20, 20, 80, 80)</b>) as shown in the above example.
2483
+ * When a shape is created with <b>beginShape()</b> and <b>endShape()</b>, its
2484
+ * attributes may be changed with <b>fill()</b> and <b>stroke()</b> within
2485
+ * <b>beginShape()</b> and <b>endShape()</b>. However, after the shape is
2486
+ * created, only the <b>setFill()</b> method can define a new fill value for
2487
+ * the <b>PShape</b>.
2488
+ *
2489
+ * ( end auto-generated )
2490
+ *
2491
+ * @webref
2492
+ * @param fill
2493
+ * @brief Set the fill value
2494
+ */
2495
+ public void setFill(int fill) {
2496
+ if (openShape) {
2497
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setFill()");
2498
+ return;
2499
+ }
2500
+
2501
+ this.fillColor = fill;
2502
+
2503
+ if (vertices != null && perVertexStyles) {
2504
+ for (int i = 0; i < vertexCount; i++) {
2505
+ setFill(i, fill);
2506
+ }
2507
+ }
2508
+ }
2509
+
2510
+ /**
2511
+ * @nowebref
2512
+ */
2513
+ public void setFill(int index, int fill) {
2514
+ if (openShape) {
2515
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setFill()");
2516
+ return;
2517
+ }
2518
+
2519
+ if (!perVertexStyles) {
2520
+ PGraphics.showWarning(PER_VERTEX_UNSUPPORTED, "setFill()");
2521
+ return;
2522
+ }
2523
+
2524
+ // make sure we allocated the vertices array and that vertex exists
2525
+ if (vertices == null || index >= vertices.length) {
2526
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getFill()");
2527
+ return;
2528
+ }
2529
+
2530
+ if (image == null) {
2531
+ vertices[index][PGraphics.A] = ((fill >> 24) & 0xFF) / 255.0f;
2532
+ vertices[index][PGraphics.R] = ((fill >> 16) & 0xFF) / 255.0f;
2533
+ vertices[index][PGraphics.G] = ((fill >> 8) & 0xFF) / 255.0f;
2534
+ vertices[index][PGraphics.B] = ((fill) & 0xFF) / 255.0f;
2535
+ }
2536
+ }
2537
+
2538
+
2539
+ public int getTint(int index) {
2540
+ // make sure we allocated the vertices array and that vertex exists
2541
+ if (vertices == null || index >= vertices.length) {
2542
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getTint()");
2543
+ return this.tintColor;
2544
+ }
2545
+
2546
+ if (image != null) {
2547
+ int a = (int) (vertices[index][PGraphics.A] * 255);
2548
+ int r = (int) (vertices[index][PGraphics.R] * 255);
2549
+ int g = (int) (vertices[index][PGraphics.G] * 255);
2550
+ int b = (int) (vertices[index][PGraphics.B] * 255);
2551
+ return (a << 24) | (r << 16) | (g << 8) | b;
2552
+ } else {
2553
+ return 0;
2554
+ }
2555
+ }
2556
+
2557
+
2558
+ public void setTint(boolean tint) {
2559
+ if (openShape) {
2560
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTint()");
2561
+ return;
2562
+ }
2563
+
2564
+ this.tint = tint;
2565
+ }
2566
+
2567
+
2568
+ public void setTint(int fill) {
2569
+ if (openShape) {
2570
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTint()");
2571
+ return;
2572
+ }
2573
+
2574
+ tintColor = fill;
2575
+
2576
+ if (vertices != null) {
2577
+ for (int i = 0; i < vertices.length; i++) {
2578
+ setFill(i, fill);
2579
+ }
2580
+ }
2581
+ }
2582
+
2583
+
2584
+ public void setTint(int index, int tint) {
2585
+ if (openShape) {
2586
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setTint()");
2587
+ return;
2588
+ }
2589
+
2590
+ // make sure we allocated the vertices array and that vertex exists
2591
+ if (vertices == null ||
2592
+ index >= vertices.length) {
2593
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setTint()");
2594
+ return;
2595
+ }
2596
+
2597
+ if (image != null) {
2598
+ vertices[index][PGraphics.A] = ((tint >> 24) & 0xFF) / 255.0f;
2599
+ vertices[index][PGraphics.R] = ((tint >> 16) & 0xFF) / 255.0f;
2600
+ vertices[index][PGraphics.G] = ((tint >> 8) & 0xFF) / 255.0f;
2601
+ vertices[index][PGraphics.B] = ((tint) & 0xFF) / 255.0f;
2602
+ }
2603
+ }
2604
+
2605
+
2606
+ public int getStroke(int index) {
2607
+ // make sure we allocated the vertices array and that vertex exists
2608
+ if (vertices == null ||
2609
+ index >= vertices.length) {
2610
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getStroke()");
2611
+ return strokeColor;
2612
+ }
2613
+
2614
+ int a = (int) (vertices[index][PGraphics.SA] * 255);
2615
+ int r = (int) (vertices[index][PGraphics.SR] * 255);
2616
+ int g = (int) (vertices[index][PGraphics.SG] * 255);
2617
+ int b = (int) (vertices[index][PGraphics.SB] * 255);
2618
+ return (a << 24) | (r << 16) | (g << 8) | b;
2619
+ }
2620
+
2621
+ /**
2622
+ * @nowebref
2623
+ */
2624
+ public void setStroke(boolean stroke) {
2625
+ if (openShape) {
2626
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStroke()");
2627
+ return;
2628
+ }
2629
+
2630
+ this.stroke = stroke;
2631
+ }
2632
+
2633
+ /**
2634
+ * ( begin auto-generated from PShape_setStroke.xml )
2635
+ *
2636
+ * The <b>setStroke()</b> method defines the outline color of a <b>PShape</b>.
2637
+ * This method is used after shapes are created or when a shape is defined
2638
+ * explicitly (e.g. <b>createShape(RECT, 20, 20, 80, 80)</b>) as shown in
2639
+ * the above example. When a shape is created with <b>beginShape()</b> and
2640
+ * <b>endShape()</b>, its attributes may be changed with <b>fill()</b> and
2641
+ * <b>stroke()</b> within <b>beginShape()</b> and <b>endShape()</b>.
2642
+ * However, after the shape is created, only the <b>setStroke()</b> method
2643
+ * can define a new stroke value for the <b>PShape</b>.
2644
+ *
2645
+ * ( end auto-generated )
2646
+ *
2647
+ * @webref
2648
+ * @param stroke
2649
+ * @brief Set the stroke value
2650
+ */
2651
+ public void setStroke(int stroke) {
2652
+ if (openShape) {
2653
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStroke()");
2654
+ return;
2655
+ }
2656
+
2657
+ strokeColor = stroke;
2658
+
2659
+ if (vertices != null && perVertexStyles) {
2660
+ for (int i = 0; i < vertices.length; i++) {
2661
+ setStroke(i, stroke);
2662
+ }
2663
+ }
2664
+ }
2665
+
2666
+ /**
2667
+ * @nowebref
2668
+ */
2669
+ public void setStroke(int index, int stroke) {
2670
+ if (openShape) {
2671
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStroke()");
2672
+ return;
2673
+ }
2674
+
2675
+ if (!perVertexStyles) {
2676
+ PGraphics.showWarning(PER_VERTEX_UNSUPPORTED, "setStroke()");
2677
+ return;
2678
+ }
2679
+
2680
+ // make sure we allocated the vertices array and that vertex exists
2681
+ if (vertices == null || index >= vertices.length) {
2682
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setStroke()");
2683
+ return;
2684
+ }
2685
+
2686
+ vertices[index][PGraphics.SA] = ((stroke >> 24) & 0xFF) / 255.0f;
2687
+ vertices[index][PGraphics.SR] = ((stroke >> 16) & 0xFF) / 255.0f;
2688
+ vertices[index][PGraphics.SG] = ((stroke >> 8) & 0xFF) / 255.0f;
2689
+ vertices[index][PGraphics.SB] = ((stroke >> 0) & 0xFF) / 255.0f;
2690
+ }
2691
+
2692
+
2693
+ public float getStrokeWeight(int index) {
2694
+ // make sure we allocated the vertices array and that vertex exists
2695
+ if (vertices == null || index >= vertices.length) {
2696
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getStrokeWeight()");
2697
+ return strokeWeight;
2698
+ }
2699
+
2700
+ return vertices[index][PGraphics.SW];
2701
+ }
2702
+
2703
+
2704
+ public void setStrokeWeight(float weight) {
2705
+ if (openShape) {
2706
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStrokeWeight()");
2707
+ return;
2708
+ }
2709
+
2710
+ strokeWeight = weight;
2711
+
2712
+ if (vertices != null && perVertexStyles) {
2713
+ for (int i = 0; i < vertexCount; i++) {
2714
+ setStrokeWeight(i, weight);
2715
+ }
2716
+ }
2717
+ }
2718
+
2719
+
2720
+ public void setStrokeWeight(int index, float weight) {
2721
+ if (openShape) {
2722
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStrokeWeight()");
2723
+ return;
2724
+ }
2725
+
2726
+ if (!perVertexStyles) {
2727
+ PGraphics.showWarning(PER_VERTEX_UNSUPPORTED, "setStrokeWeight()");
2728
+ return;
2729
+ }
2730
+
2731
+ // make sure we allocated the vertices array and that vertex exists
2732
+ if (vertices == null || index >= vertices.length) {
2733
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setStrokeWeight()");
2734
+ return;
2735
+ }
2736
+
2737
+ vertices[index][PGraphics.SW] = weight;
2738
+ }
2739
+
2740
+
2741
+ public void setStrokeJoin(int join) {
2742
+ if (openShape) {
2743
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStrokeJoin()");
2744
+ return;
2745
+ }
2746
+
2747
+ strokeJoin = join;
2748
+ }
2749
+
2750
+
2751
+ public void setStrokeCap(int cap) {
2752
+ if (openShape) {
2753
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setStrokeCap()");
2754
+ return;
2755
+ }
2756
+
2757
+ strokeCap = cap;
2758
+ }
2759
+
2760
+
2761
+ public int getAmbient(int index) {
2762
+ // make sure we allocated the vertices array and that vertex exists
2763
+ if (vertices == null || index >= vertices.length) {
2764
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getAmbient()");
2765
+ return ambientColor;
2766
+ }
2767
+
2768
+ int r = (int) (vertices[index][PGraphics.AR] * 255);
2769
+ int g = (int) (vertices[index][PGraphics.AG] * 255);
2770
+ int b = (int) (vertices[index][PGraphics.AB] * 255);
2771
+ return 0xff000000 | (r << 16) | (g << 8) | b;
2772
+ }
2773
+
2774
+
2775
+ public void setAmbient(int ambient) {
2776
+ if (openShape) {
2777
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setAmbient()");
2778
+ return;
2779
+ }
2780
+
2781
+ ambientColor = ambient;
2782
+
2783
+ if (vertices != null) {
2784
+ for (int i = 0; i < vertices.length; i++) {
2785
+ setAmbient(i, ambient);
2786
+ }
2787
+ }
2788
+ }
2789
+
2790
+
2791
+ public void setAmbient(int index, int ambient) {
2792
+ if (openShape) {
2793
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setAmbient()");
2794
+ return;
2795
+ }
2796
+
2797
+ // make sure we allocated the vertices array and that vertex exists
2798
+ if (vertices == null || index >= vertices.length) {
2799
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setAmbient()");
2800
+ return;
2801
+ }
2802
+
2803
+ vertices[index][PGraphics.AR] = ((ambient >> 16) & 0xFF) / 255.0f;
2804
+ vertices[index][PGraphics.AG] = ((ambient >> 8) & 0xFF) / 255.0f;
2805
+ vertices[index][PGraphics.AB] = ((ambient >> 0) & 0xFF) / 255.0f;
2806
+ }
2807
+
2808
+
2809
+ public int getSpecular(int index) {
2810
+ // make sure we allocated the vertices array and that vertex exists
2811
+ if (vertices == null || index >= vertices.length) {
2812
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getSpecular()");
2813
+ return specularColor;
2814
+ }
2815
+
2816
+ int r = (int) (vertices[index][PGraphics.SPR] * 255);
2817
+ int g = (int) (vertices[index][PGraphics.SPG] * 255);
2818
+ int b = (int) (vertices[index][PGraphics.SPB] * 255);
2819
+ return 0xff000000 | (r << 16) | (g << 8) | b;
2820
+ }
2821
+
2822
+
2823
+ public void setSpecular(int specular) {
2824
+ if (openShape) {
2825
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setSpecular()");
2826
+ return;
2827
+ }
2828
+
2829
+ specularColor = specular;
2830
+
2831
+ if (vertices != null) {
2832
+ for (int i = 0; i < vertices.length; i++) {
2833
+ setSpecular(i, specular);
2834
+ }
2835
+ }
2836
+ }
2837
+
2838
+
2839
+ public void setSpecular(int index, int specular) {
2840
+ if (openShape) {
2841
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setSpecular()");
2842
+ return;
2843
+ }
2844
+
2845
+ // make sure we allocated the vertices array and that vertex exists
2846
+ if (vertices == null || index >= vertices.length) {
2847
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setSpecular()");
2848
+ return;
2849
+ }
2850
+
2851
+ vertices[index][PGraphics.SPR] = ((specular >> 16) & 0xFF) / 255.0f;
2852
+ vertices[index][PGraphics.SPG] = ((specular >> 8) & 0xFF) / 255.0f;
2853
+ vertices[index][PGraphics.SPB] = ((specular >> 0) & 0xFF) / 255.0f;
2854
+ }
2855
+
2856
+
2857
+ public int getEmissive(int index) {
2858
+ // make sure we allocated the vertices array and that vertex exists
2859
+ if (vertices == null || index >= vertices.length) {
2860
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getEmissive()");
2861
+ return emissiveColor;
2862
+ }
2863
+
2864
+ int r = (int) (vertices[index][PGraphics.ER] * 255);
2865
+ int g = (int) (vertices[index][PGraphics.EG] * 255);
2866
+ int b = (int) (vertices[index][PGraphics.EB] * 255);
2867
+ return 0xff000000 | (r << 16) | (g << 8) | b;
2868
+ }
2869
+
2870
+
2871
+ public void setEmissive(int emissive) {
2872
+ if (openShape) {
2873
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setEmissive()");
2874
+ return;
2875
+ }
2876
+
2877
+ emissiveColor = emissive;
2878
+
2879
+ if (vertices != null) {
2880
+ for (int i = 0; i < vertices.length; i++) {
2881
+ setEmissive(i, emissive);
2882
+ }
2883
+ }
2884
+ }
2885
+
2886
+
2887
+ public void setEmissive(int index, int emissive) {
2888
+ if (openShape) {
2889
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setEmissive()");
2890
+ return;
2891
+ }
2892
+
2893
+ // make sure we allocated the vertices array and that vertex exists
2894
+ if (vertices == null ||
2895
+ index >= vertices.length) {
2896
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setEmissive()");
2897
+ return;
2898
+ }
2899
+
2900
+ vertices[index][PGraphics.ER] = ((emissive >> 16) & 0xFF) / 255.0f;
2901
+ vertices[index][PGraphics.EG] = ((emissive >> 8) & 0xFF) / 255.0f;
2902
+ vertices[index][PGraphics.EB] = ((emissive >> 0) & 0xFF) / 255.0f;
2903
+ }
2904
+
2905
+
2906
+ public float getShininess(int index) {
2907
+ // make sure we allocated the vertices array and that vertex exists
2908
+ if (vertices == null ||
2909
+ index >= vertices.length) {
2910
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "getShininess()");
2911
+ return shininess;
2912
+ }
2913
+
2914
+ return vertices[index][PGraphics.SHINE];
2915
+ }
2916
+
2917
+
2918
+ public void setShininess(float shine) {
2919
+ if (openShape) {
2920
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setShininess()");
2921
+ return;
2922
+ }
2923
+
2924
+ shininess = shine;
2925
+
2926
+ if (vertices != null) {
2927
+ for (int i = 0; i < vertices.length; i++) {
2928
+ setShininess(i, shine);
2929
+ }
2930
+ }
2931
+ }
2932
+
2933
+
2934
+ public void setShininess(int index, float shine) {
2935
+ if (openShape) {
2936
+ PGraphics.showWarning(INSIDE_BEGIN_END_ERROR, "setShininess()");
2937
+ return;
2938
+ }
2939
+
2940
+ // make sure we allocated the vertices array and that vertex exists
2941
+ if (vertices == null ||
2942
+ index >= vertices.length) {
2943
+ PGraphics.showWarning(NO_SUCH_VERTEX_ERROR + " (" + index + ")", "setShininess()");
2944
+ return;
2945
+ }
2946
+
2947
+
2948
+ vertices[index][PGraphics.SHINE] = shine;
2949
+ }
2950
+
2951
+
2952
+ public int[] getVertexCodes() {
2953
+ if (vertexCodes == null) {
2954
+ return null;
2955
+ }
2956
+ if (vertexCodes.length != vertexCodeCount) {
2957
+ vertexCodes = PApplet.subset(vertexCodes, 0, vertexCodeCount);
2958
+ }
2959
+ return vertexCodes;
2960
+ }
2961
+
2962
+
2963
+ public int getVertexCodeCount() {
2964
+ return vertexCodeCount;
2965
+ }
2966
+
2967
+
2968
+ /**
2969
+ * One of VERTEX, BEZIER_VERTEX, CURVE_VERTEX, or BREAK.
2970
+ */
2971
+ public int getVertexCode(int index) {
2972
+ return vertexCodes[index];
2973
+ }
2974
+
2975
+
2976
+ public boolean isClosed() {
2977
+ return close;
2978
+ }
2979
+
2980
+
2981
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2982
+
2983
+
2984
+ /**
2985
+ * Return true if this x, y coordinate is part of this shape. Only works
2986
+ * with PATH shapes or GROUP shapes that contain other GROUPs or PATHs.
2987
+ */
2988
+ public boolean contains(float x, float y) {
2989
+ if (family == PATH) {
2990
+ PVector p = new PVector(x, y);
2991
+ if (matrix != null) {
2992
+ // apply the inverse transformation matrix to the point coordinates
2993
+ PMatrix inverseCoords = matrix.get();
2994
+ // TODO why is this called twice? [fry 190724]
2995
+ // commit was https://github.com/processing/processing/commit/027fc7a4f8e8d0a435366eae754304eea282512a
2996
+ inverseCoords.invert(); // maybe cache this?
2997
+ inverseCoords.invert(); // maybe cache this?
2998
+ inverseCoords.mult(new PVector(x, y), p);
2999
+ }
3000
+
3001
+ // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
3002
+ boolean c = false;
3003
+ for (int i = 0, j = vertexCount-1; i < vertexCount; j = i++) {
3004
+ if (((vertices[i][Y] > p.y) != (vertices[j][Y] > p.y)) &&
3005
+ (p.x <
3006
+ (vertices[j][X]-vertices[i][X]) *
3007
+ (y-vertices[i][Y]) /
3008
+ (vertices[j][1]-vertices[i][Y]) +
3009
+ vertices[i][X])) {
3010
+ c = !c;
3011
+ }
3012
+ }
3013
+ return c;
3014
+
3015
+ } else if (family == GROUP) {
3016
+ // If this is a group, loop through children until we find one that
3017
+ // contains the supplied coordinates. If a child does not support
3018
+ // contains() throw a warning and continue.
3019
+ for (int i = 0; i < childCount; i++) {
3020
+ if (children[i].contains(x, y)) return true;
3021
+ }
3022
+ return false;
3023
+
3024
+ } else {
3025
+ // https://github.com/processing/processing/issues/1280
3026
+ throw new IllegalArgumentException("The contains() method is only implemented for paths.");
3027
+ }
3028
+ }
3029
+
3030
+
3031
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3032
+
3033
+
3034
+ // translate, rotate, scale, apply (no push/pop)
3035
+ // these each call matrix.translate, etc
3036
+ // if matrix is null when one is called,
3037
+ // it is created and set to identity
3038
+
3039
+
3040
+ /**
3041
+ * ( begin auto-generated from PShape_translate.xml )
3042
+ *
3043
+ * Specifies an amount to displace the shape. The <b>x</b> parameter
3044
+ * specifies left/right translation, the <b>y</b> parameter specifies
3045
+ * up/down translation, and the <b>z</b> parameter specifies translations
3046
+ * toward/away from the screen. Subsequent calls to the method accumulates
3047
+ * the effect. For example, calling <b>translate(50, 0)</b> and then
3048
+ * <b>translate(20, 0)</b> is the same as <b>translate(70, 0)</b>. This
3049
+ * transformation is applied directly to the shape, it's not refreshed each
3050
+ * time <b>draw()</b> is run.
3051
+ *
3052
+ * Using this method with the <b>z</b> parameter requires using the P3D
3053
+ * parameter in combination with size.
3054
+ *
3055
+ * ( end auto-generated )
3056
+ * @webref pshape:method
3057
+ * @usage web_application
3058
+ * @brief Displaces the shape
3059
+ * @param x left/right translation
3060
+ * @param y up/down translation
3061
+ * @see PShape#rotate(float)
3062
+ * @see PShape#scale(float)
3063
+ * @see PShape#resetMatrix()
3064
+ */
3065
+ public void translate(float x, float y) {
3066
+ checkMatrix(2);
3067
+ matrix.translate(x, y);
3068
+ }
3069
+
3070
+ /**
3071
+ * @param z forward/back translation
3072
+ */
3073
+ public void translate(float x, float y, float z) {
3074
+ checkMatrix(3);
3075
+ matrix.translate(x, y, z);
3076
+ }
3077
+
3078
+ /**
3079
+ * ( begin auto-generated from PShape_rotateX.xml )
3080
+ *
3081
+ * Rotates a shape around the x-axis the amount specified by the
3082
+ * <b>angle</b> parameter. Angles should be specified in radians (values
3083
+ * from 0 to TWO_PI) or converted to radians with the <b>radians()</b> method.
3084
+ *
3085
+ * Shapes are always rotated around the upper-left corner of their bounding
3086
+ * box. Positive numbers rotate objects in a clockwise direction.
3087
+ * Subsequent calls to the method accumulates the effect. For example,
3088
+ * calling <b>rotateX(HALF_PI)</b> and then <b>rotateX(HALF_PI)</b> is the
3089
+ * same as <b>rotateX(PI)</b>. This transformation is applied directly to
3090
+ * the shape, it's not refreshed each time <b>draw()</b> is run.
3091
+ *
3092
+ * This method requires a 3D renderer. You need to use P3D as a third
3093
+ * parameter for the <b>size()</b> function as shown in the example above.
3094
+ *
3095
+ * ( end auto-generated )
3096
+ * @webref pshape:method
3097
+ * @usage web_application
3098
+ * @brief Rotates the shape around the x-axis
3099
+ * @param angle angle of rotation specified in radians
3100
+ * @see PShape#rotate(float)
3101
+ * @see PShape#rotateY(float)
3102
+ * @see PShape#rotateZ(float)
3103
+ * @see PShape#scale(float)
3104
+ * @see PShape#translate(float, float)
3105
+ * @see PShape#resetMatrix()
3106
+ */
3107
+ public void rotateX(float angle) {
3108
+ rotate(angle, 1, 0, 0);
3109
+ }
3110
+
3111
+ /**
3112
+ * ( begin auto-generated from PShape_rotateY.xml )
3113
+ *
3114
+ * Rotates a shape around the y-axis the amount specified by the
3115
+ * <b>angle</b> parameter. Angles should be specified in radians (values
3116
+ * from 0 to TWO_PI) or converted to radians with the <b>radians()</b> method.
3117
+ *
3118
+ * Shapes are always rotated around the upper-left corner of their bounding
3119
+ * box. Positive numbers rotate objects in a clockwise direction.
3120
+ * Subsequent calls to the method accumulates the effect. For example,
3121
+ * calling <b>rotateY(HALF_PI)</b> and then <b>rotateY(HALF_PI)</b> is the
3122
+ * same as <b>rotateY(PI)</b>. This transformation is applied directly to
3123
+ * the shape, it's not refreshed each time <b>draw()</b> is run.
3124
+ *
3125
+ * This method requires a 3D renderer. You need to use P3D as a third
3126
+ * parameter for the <b>size()</b> function as shown in the example above.
3127
+ *
3128
+ * ( end auto-generated )
3129
+ *
3130
+ * @webref pshape:method
3131
+ * @usage web_application
3132
+ * @brief Rotates the shape around the y-axis
3133
+ * @param angle angle of rotation specified in radians
3134
+ * @see PShape#rotate(float)
3135
+ * @see PShape#rotateX(float)
3136
+ * @see PShape#rotateZ(float)
3137
+ * @see PShape#scale(float)
3138
+ * @see PShape#translate(float, float)
3139
+ * @see PShape#resetMatrix()
3140
+ */
3141
+ public void rotateY(float angle) {
3142
+ rotate(angle, 0, 1, 0);
3143
+ }
3144
+
3145
+
3146
+ /**
3147
+ * ( begin auto-generated from PShape_rotateZ.xml )
3148
+ *
3149
+ * Rotates a shape around the z-axis the amount specified by the
3150
+ * <b>angle</b> parameter. Angles should be specified in radians (values
3151
+ * from 0 to TWO_PI) or converted to radians with the <b>radians()</b> method.
3152
+ *
3153
+ * Shapes are always rotated around the upper-left corner of their bounding
3154
+ * box. Positive numbers rotate objects in a clockwise direction.
3155
+ * Subsequent calls to the method accumulates the effect. For example,
3156
+ * calling <b>rotateZ(HALF_PI)</b> and then <b>rotateZ(HALF_PI)</b> is the
3157
+ * same as <b>rotateZ(PI)</b>. This transformation is applied directly to
3158
+ * the shape, it's not refreshed each time <b>draw()</b> is run.
3159
+ *
3160
+ * This method requires a 3D renderer. You need to use P3D as a third
3161
+ * parameter for the <b>size()</b> function as shown in the example above.
3162
+ *
3163
+ * ( end auto-generated )
3164
+ * @webref pshape:method
3165
+ * @usage web_application
3166
+ * @brief Rotates the shape around the z-axis
3167
+ * @param angle angle of rotation specified in radians
3168
+ * @see PShape#rotate(float)
3169
+ * @see PShape#rotateX(float)
3170
+ * @see PShape#rotateY(float)
3171
+ * @see PShape#scale(float)
3172
+ * @see PShape#translate(float, float)
3173
+ * @see PShape#resetMatrix()
3174
+ */
3175
+ public void rotateZ(float angle) {
3176
+ rotate(angle, 0, 0, 1);
3177
+ }
3178
+
3179
+ /**
3180
+ * ( begin auto-generated from PShape_rotate.xml )
3181
+ *
3182
+ * Rotates a shape the amount specified by the <b>angle</b> parameter.
3183
+ * Angles should be specified in radians (values from 0 to TWO_PI) or
3184
+ * converted to radians with the <b>radians()</b> method.
3185
+ *
3186
+ * Shapes are always rotated around the upper-left corner of their bounding
3187
+ * box. Positive numbers rotate objects in a clockwise direction.
3188
+ * Transformations apply to everything that happens after and subsequent
3189
+ * calls to the method accumulates the effect. For example, calling
3190
+ * <b>rotate(HALF_PI)</b> and then <b>rotate(HALF_PI)</b> is the same as
3191
+ * <b>rotate(PI)</b>. This transformation is applied directly to the shape,
3192
+ * it's not refreshed each time <b>draw()</b> is run.
3193
+ *
3194
+ * ( end auto-generated )
3195
+ * @webref pshape:method
3196
+ * @usage web_application
3197
+ * @brief Rotates the shape
3198
+ * @param angle angle of rotation specified in radians
3199
+ * @see PShape#rotateX(float)
3200
+ * @see PShape#rotateY(float)
3201
+ * @see PShape#rotateZ(float)
3202
+ * @see PShape#scale(float)
3203
+ * @see PShape#translate(float, float)
3204
+ * @see PShape#resetMatrix()
3205
+ */
3206
+ public void rotate(float angle) {
3207
+ checkMatrix(2); // at least 2...
3208
+ matrix.rotate(angle);
3209
+ }
3210
+
3211
+ /**
3212
+ * @nowebref
3213
+ */
3214
+ public void rotate(float angle, float v0, float v1, float v2) {
3215
+ checkMatrix(3);
3216
+ float norm2 = v0 * v0 + v1 * v1 + v2 * v2;
3217
+ if (Math.abs(norm2 - 1) > EPSILON) {
3218
+ // The rotation vector is not normalized.
3219
+ float norm = PApplet.sqrt(norm2);
3220
+ v0 /= norm;
3221
+ v1 /= norm;
3222
+ v2 /= norm;
3223
+ }
3224
+ matrix.rotate(angle, v0, v1, v2);
3225
+ }
3226
+
3227
+
3228
+ //
3229
+
3230
+ /**
3231
+ * ( begin auto-generated from PShape_scale.xml )
3232
+ *
3233
+ * Increases or decreases the size of a shape by expanding and contracting
3234
+ * vertices. Shapes always scale from the relative origin of their bounding
3235
+ * box. Scale values are specified as decimal percentages. For example, the
3236
+ * method call <b>scale(2.0)</b> increases the dimension of a shape by
3237
+ * 200%. Subsequent calls to the method multiply the effect. For example,
3238
+ * calling <b>scale(2.0)</b> and then <b>scale(1.5)</b> is the same as
3239
+ * <b>scale(3.0)</b>. This transformation is applied directly to the shape,
3240
+ * it's not refreshed each time <b>draw()</b> is run.
3241
+ *
3242
+ * Using this method with the <b>z</b> parameter requires using the P3D
3243
+ * parameter in combination with size.
3244
+ *
3245
+ * ( end auto-generated )
3246
+ * @webref pshape:method
3247
+ * @usage web_application
3248
+ * @brief Increases and decreases the size of a shape
3249
+ * @param s percentate to scale the object
3250
+ * @see PShape#rotate(float)
3251
+ * @see PShape#translate(float, float)
3252
+ * @see PShape#resetMatrix()
3253
+ */
3254
+ public void scale(float s) {
3255
+ checkMatrix(2); // at least 2...
3256
+ matrix.scale(s);
3257
+ }
3258
+
3259
+
3260
+ public void scale(float x, float y) {
3261
+ checkMatrix(2);
3262
+ matrix.scale(x, y);
3263
+ }
3264
+
3265
+ /**
3266
+ * @param x percentage to scale the object in the x-axis
3267
+ * @param y percentage to scale the object in the y-axis
3268
+ * @param z percentage to scale the object in the z-axis
3269
+ */
3270
+ public void scale(float x, float y, float z) {
3271
+ checkMatrix(3);
3272
+ matrix.scale(x, y, z);
3273
+ }
3274
+
3275
+
3276
+ //
3277
+
3278
+ /**
3279
+ * ( begin auto-generated from PShape_resetMatrix.xml )
3280
+ *
3281
+ * Replaces the current matrix of a shape with the identity matrix. The
3282
+ * equivalent function in OpenGL is glLoadIdentity().
3283
+ *
3284
+ * ( end auto-generated )
3285
+ * @webref pshape:method
3286
+ * @brief Replaces the current matrix of a shape with the identity matrix
3287
+ * @usage web_application
3288
+ * @see PShape#rotate(float)
3289
+ * @see PShape#scale(float)
3290
+ * @see PShape#translate(float, float)
3291
+ */
3292
+ public void resetMatrix() {
3293
+ checkMatrix(2);
3294
+ matrix.reset();
3295
+ }
3296
+
3297
+
3298
+ public void applyMatrix(PMatrix source) {
3299
+ if (source instanceof PMatrix2D) {
3300
+ applyMatrix((PMatrix2D) source);
3301
+ } else if (source instanceof PMatrix3D) {
3302
+ applyMatrix((PMatrix3D) source);
3303
+ }
3304
+ }
3305
+
3306
+
3307
+ public void applyMatrix(PMatrix2D source) {
3308
+ applyMatrix(source.m00, source.m01, 0, source.m02,
3309
+ source.m10, source.m11, 0, source.m12,
3310
+ 0, 0, 1, 0,
3311
+ 0, 0, 0, 1);
3312
+ }
3313
+
3314
+
3315
+ public void applyMatrix(float n00, float n01, float n02,
3316
+ float n10, float n11, float n12) {
3317
+ checkMatrix(2);
3318
+ matrix.apply(n00, n01, n02,
3319
+ n10, n11, n12);
3320
+ }
3321
+
3322
+
3323
+ public void applyMatrix(PMatrix3D source) {
3324
+ applyMatrix(source.m00, source.m01, source.m02, source.m03,
3325
+ source.m10, source.m11, source.m12, source.m13,
3326
+ source.m20, source.m21, source.m22, source.m23,
3327
+ source.m30, source.m31, source.m32, source.m33);
3328
+ }
3329
+
3330
+
3331
+ public void applyMatrix(float n00, float n01, float n02, float n03,
3332
+ float n10, float n11, float n12, float n13,
3333
+ float n20, float n21, float n22, float n23,
3334
+ float n30, float n31, float n32, float n33) {
3335
+ checkMatrix(3);
3336
+ matrix.apply(n00, n01, n02, n03,
3337
+ n10, n11, n12, n13,
3338
+ n20, n21, n22, n23,
3339
+ n30, n31, n32, n33);
3340
+ }
3341
+
3342
+
3343
+ //
3344
+
3345
+
3346
+ /**
3347
+ * Make sure that the shape's matrix is 1) not null, and 2) has a matrix
3348
+ * that can handle <em>at least</em> the specified number of dimensions.
3349
+ */
3350
+ protected void checkMatrix(int dimensions) {
3351
+ if (matrix == null) {
3352
+ if (dimensions == 2) {
3353
+ matrix = new PMatrix2D();
3354
+ } else {
3355
+ matrix = new PMatrix3D();
3356
+ }
3357
+ } else if (dimensions == 3 && (matrix instanceof PMatrix2D)) {
3358
+ // time for an upgrayedd for a double dose of my pimpin'
3359
+ matrix = new PMatrix3D(matrix);
3360
+ }
3361
+ }
3362
+
3363
+
3364
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3365
+
3366
+
3367
+ /**
3368
+ * Center the shape based on its bounding box. Can't assume
3369
+ * that the bounding box is 0, 0, width, height. Common case will be
3370
+ * opening a letter size document in Illustrator, and drawing something
3371
+ * in the middle, then reading it in as an svg file.
3372
+ * This will also need to flip the y axis (scale(1, -1)) in cases
3373
+ * like Adobe Illustrator where the coordinates start at the bottom.
3374
+ */
3375
+ // public void center() {
3376
+ // }
3377
+
3378
+
3379
+ /**
3380
+ * Set the pivot point for all transformations.
3381
+ */
3382
+ // public void pivot(float x, float y) {
3383
+ // px = x;
3384
+ // py = y;
3385
+ // }
3386
+
3387
+
3388
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3389
+
3390
+
3391
+ public void colorMode(int mode) {
3392
+ colorMode(mode, colorModeX, colorModeY, colorModeZ, colorModeA);
3393
+ }
3394
+
3395
+ /**
3396
+ * @param max range for all color elements
3397
+ */
3398
+ public void colorMode(int mode, float max) {
3399
+ colorMode(mode, max, max, max, max);
3400
+ }
3401
+
3402
+
3403
+ /**
3404
+ * @param maxX range for the red or hue depending on the current color mode
3405
+ * @param maxY range for the green or saturation depending on the current color mode
3406
+ * @param maxZ range for the blue or brightness depending on the current color mode
3407
+ */
3408
+ public void colorMode(int mode, float maxX, float maxY, float maxZ) {
3409
+ colorMode(mode, maxX, maxY, maxZ, colorModeA);
3410
+ }
3411
+
3412
+ /**
3413
+ * @param maxA range for the alpha
3414
+ */
3415
+ public void colorMode(int mode,
3416
+ float maxX, float maxY, float maxZ, float maxA) {
3417
+ colorMode = mode;
3418
+
3419
+ colorModeX = maxX; // still needs to be set for hsb
3420
+ colorModeY = maxY;
3421
+ colorModeZ = maxZ;
3422
+ colorModeA = maxA;
3423
+
3424
+ // if color max values are all 1, then no need to scale
3425
+ colorModeScale =
3426
+ ((maxA != 1) || (maxX != maxY) || (maxY != maxZ) || (maxZ != maxA));
3427
+
3428
+ // if color is rgb/0..255 this will make it easier for the
3429
+ // red() green() etc functions
3430
+ colorModeDefault = (colorMode == RGB) &&
3431
+ (colorModeA == 255) && (colorModeX == 255) &&
3432
+ (colorModeY == 255) && (colorModeZ == 255);
3433
+ }
3434
+
3435
+
3436
+ protected void colorCalc(int rgb) {
3437
+ if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) {
3438
+ colorCalc((float) rgb);
3439
+
3440
+ } else {
3441
+ colorCalcARGB(rgb, colorModeA);
3442
+ }
3443
+ }
3444
+
3445
+
3446
+ protected void colorCalc(int rgb, float alpha) {
3447
+ if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above
3448
+ colorCalc((float) rgb, alpha);
3449
+
3450
+ } else {
3451
+ colorCalcARGB(rgb, alpha);
3452
+ }
3453
+ }
3454
+
3455
+
3456
+ protected void colorCalc(float gray) {
3457
+ colorCalc(gray, colorModeA);
3458
+ }
3459
+
3460
+
3461
+ protected void colorCalc(float gray, float alpha) {
3462
+ if (gray > colorModeX) gray = colorModeX;
3463
+ if (alpha > colorModeA) alpha = colorModeA;
3464
+
3465
+ if (gray < 0) gray = 0;
3466
+ if (alpha < 0) alpha = 0;
3467
+
3468
+ calcR = colorModeScale ? (gray / colorModeX) : gray;
3469
+ calcG = calcR;
3470
+ calcB = calcR;
3471
+ calcA = colorModeScale ? (alpha / colorModeA) : alpha;
3472
+
3473
+ calcRi = (int)(calcR*255); calcGi = (int)(calcG*255);
3474
+ calcBi = (int)(calcB*255); calcAi = (int)(calcA*255);
3475
+ calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi;
3476
+ calcAlpha = (calcAi != 255);
3477
+ }
3478
+
3479
+
3480
+ protected void colorCalc(float x, float y, float z) {
3481
+ colorCalc(x, y, z, colorModeA);
3482
+ }
3483
+
3484
+
3485
+ protected void colorCalc(float x, float y, float z, float a) {
3486
+ if (x > colorModeX) x = colorModeX;
3487
+ if (y > colorModeY) y = colorModeY;
3488
+ if (z > colorModeZ) z = colorModeZ;
3489
+ if (a > colorModeA) a = colorModeA;
3490
+
3491
+ if (x < 0) x = 0;
3492
+ if (y < 0) y = 0;
3493
+ if (z < 0) z = 0;
3494
+ if (a < 0) a = 0;
3495
+
3496
+ switch (colorMode) {
3497
+ case RGB:
3498
+ if (colorModeScale) {
3499
+ calcR = x / colorModeX;
3500
+ calcG = y / colorModeY;
3501
+ calcB = z / colorModeZ;
3502
+ calcA = a / colorModeA;
3503
+ } else {
3504
+ calcR = x; calcG = y; calcB = z; calcA = a;
3505
+ }
3506
+ break;
3507
+
3508
+ case HSB:
3509
+ x /= colorModeX; // h
3510
+ y /= colorModeY; // s
3511
+ z /= colorModeZ; // b
3512
+
3513
+ calcA = colorModeScale ? (a/colorModeA) : a;
3514
+
3515
+ if (y == 0) { // saturation == 0
3516
+ calcR = calcG = calcB = z;
3517
+
3518
+ } else {
3519
+ float which = (x - (int)x) * 6.0f;
3520
+ float f = which - (int)which;
3521
+ float p = z * (1.0f - y);
3522
+ float q = z * (1.0f - y * f);
3523
+ float t = z * (1.0f - (y * (1.0f - f)));
3524
+
3525
+ switch ((int)which) {
3526
+ case 0: calcR = z; calcG = t; calcB = p; break;
3527
+ case 1: calcR = q; calcG = z; calcB = p; break;
3528
+ case 2: calcR = p; calcG = z; calcB = t; break;
3529
+ case 3: calcR = p; calcG = q; calcB = z; break;
3530
+ case 4: calcR = t; calcG = p; calcB = z; break;
3531
+ case 5: calcR = z; calcG = p; calcB = q; break;
3532
+ }
3533
+ }
3534
+ break;
3535
+ }
3536
+ calcRi = (int)(255*calcR); calcGi = (int)(255*calcG);
3537
+ calcBi = (int)(255*calcB); calcAi = (int)(255*calcA);
3538
+ calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi;
3539
+ calcAlpha = (calcAi != 255);
3540
+ }
3541
+
3542
+
3543
+ protected void colorCalcARGB(int argb, float alpha) {
3544
+ if (alpha == colorModeA) {
3545
+ calcAi = (argb >> 24) & 0xff;
3546
+ calcColor = argb;
3547
+ } else {
3548
+ calcAi = (int) (((argb >> 24) & 0xff) * (alpha / colorModeA));
3549
+ calcColor = (calcAi << 24) | (argb & 0xFFFFFF);
3550
+ }
3551
+ calcRi = (argb >> 16) & 0xff;
3552
+ calcGi = (argb >> 8) & 0xff;
3553
+ calcBi = argb & 0xff;
3554
+ calcA = calcAi / 255.0f;
3555
+ calcR = calcRi / 255.0f;
3556
+ calcG = calcGi / 255.0f;
3557
+ calcB = calcBi / 255.0f;
3558
+ calcAlpha = (calcAi != 255);
3559
+ }
3560
+
3561
+ }