p5 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/{src → dist}/accessibility/color_namer.js +48 -3
  2. package/{src → dist}/accessibility/describe.js +2 -2
  3. package/{src → dist}/accessibility/gridOutput.js +2 -2
  4. package/dist/accessibility/index.js +60 -0
  5. package/{src → dist}/accessibility/outputs.js +2 -2
  6. package/{src → dist}/accessibility/textOutput.js +2 -2
  7. package/dist/app.js +120 -0
  8. package/{src → dist}/color/color_conversion.js +48 -10
  9. package/{src → dist}/color/color_spaces/hsb.js +3 -1
  10. package/dist/color/creating_reading.js +3 -0
  11. package/dist/color/index.js +13 -0
  12. package/dist/color/p5.Color.culori.js +1 -0
  13. package/dist/color/p5.Color.js +3 -0
  14. package/{src → dist}/color/setting.js +9 -6
  15. package/{src/core/constants.js → dist/constants-C-g_eAdC.js} +266 -130
  16. package/{src → dist}/core/States.js +3 -1
  17. package/dist/core/constants.js +1 -0
  18. package/{src → dist}/core/environment.js +7 -6
  19. package/{src → dist}/core/friendly_errors/browser_errors.js +1 -1
  20. package/{src → dist}/core/friendly_errors/fes_core.js +14 -44
  21. package/{src → dist}/core/friendly_errors/file_errors.js +6 -3
  22. package/dist/core/friendly_errors/index.js +23 -0
  23. package/dist/core/friendly_errors/param_validator.js +5455 -0
  24. package/{src → dist}/core/friendly_errors/sketch_reader.js +50 -4
  25. package/{src → dist}/core/friendly_errors/sketch_verifier.js +6 -6
  26. package/{src → dist}/core/friendly_errors/stacktrace.js +3 -5
  27. package/{src → dist}/core/friendly_errors/validate_params.js +50 -41
  28. package/{src → dist}/core/helpers.js +9 -6
  29. package/dist/core/init.js +105 -0
  30. package/dist/core/internationalization.js +302 -0
  31. package/dist/core/legacy.js +73 -0
  32. package/dist/core/main.js +44 -0
  33. package/dist/core/noop.js +3 -0
  34. package/dist/core/p5.Graphics.js +40 -0
  35. package/dist/core/p5.Renderer.js +11 -0
  36. package/dist/core/p5.Renderer2D.js +44 -0
  37. package/dist/core/reference.js +1 -0
  38. package/dist/core/rendering.js +40 -0
  39. package/{src → dist}/core/structure.js +3 -3
  40. package/{src → dist}/core/transform.js +2 -2
  41. package/{src/color/creating_reading.js → dist/creating_reading-D4AAKRbx.js} +841 -13
  42. package/{src → dist}/data/index.js +3 -1
  43. package/{src → dist}/data/local_storage.js +2 -8
  44. package/{src → dist}/dom/dom.js +11 -5
  45. package/dist/dom/index.js +18 -0
  46. package/{src → dist}/dom/p5.Element.js +14 -12
  47. package/{src → dist}/dom/p5.File.js +4 -4
  48. package/{src → dist}/dom/p5.MediaElement.js +10 -4
  49. package/{src → dist}/events/acceleration.js +2 -2
  50. package/{src → dist}/events/index.js +3 -1
  51. package/{src → dist}/events/keyboard.js +14 -11
  52. package/{src → dist}/events/pointer.js +16 -17
  53. package/dist/image/const.js +9 -0
  54. package/{src → dist}/image/filterRenderer2D.js +57 -37
  55. package/{src → dist}/image/filters.js +1 -3
  56. package/dist/image/image.js +40 -0
  57. package/dist/image/index.js +51 -0
  58. package/dist/image/loading_displaying.js +40 -0
  59. package/dist/image/p5.Image.js +11 -0
  60. package/{src → dist}/image/pixels.js +4 -3
  61. package/{src → dist}/io/csv.js +72 -70
  62. package/dist/io/files.js +40 -0
  63. package/dist/io/index.js +51 -0
  64. package/{src → dist}/io/p5.Table.js +6 -6
  65. package/{src → dist}/io/p5.TableRow.js +3 -4
  66. package/{src → dist}/io/p5.XML.js +2 -5
  67. package/{src → dist}/io/utilities.js +1 -1
  68. package/{src/core/p5.Renderer2D.js → dist/main-s72KWcUy.js} +735 -57
  69. package/{src → dist}/math/Matrices/Matrix.js +10 -8
  70. package/{src → dist}/math/Matrices/MatrixInterface.js +5 -3
  71. package/{src → dist}/math/Matrices/MatrixNumjs.js +12 -26
  72. package/{src → dist}/math/calculation.js +2 -2
  73. package/{src → dist}/math/index.js +6 -3
  74. package/{src → dist}/math/math.js +2 -2
  75. package/{src → dist}/math/noise.js +2 -2
  76. package/{src → dist}/math/p5.Matrix.js +7 -4
  77. package/{src → dist}/math/p5.Vector.js +6 -6
  78. package/{src → dist}/math/random.js +2 -2
  79. package/{src → dist}/math/trigonometry.js +16 -15
  80. package/{src/image/p5.Image.js → dist/p5.Renderer-CwAYZOC2.js} +390 -19
  81. package/dist/rendering--aAe5aq3.js +24925 -0
  82. package/{src → dist}/shape/2d_primitives.js +18 -17
  83. package/{src → dist}/shape/attributes.js +18 -17
  84. package/{src → dist}/shape/curves.js +2 -2
  85. package/{src → dist}/shape/custom_shapes.js +44 -64
  86. package/{src → dist}/shape/index.js +10 -2
  87. package/{src → dist}/shape/vertex.js +2 -3
  88. package/dist/type/index.js +25 -0
  89. package/{src → dist}/type/lib/Typr.js +76 -94
  90. package/{src → dist}/type/p5.Font.js +37 -61
  91. package/{src → dist}/type/textCore.js +34 -57
  92. package/{src → dist}/type/unicodeRanges.js +3 -1
  93. package/{src → dist}/utilities/conversion.js +2 -2
  94. package/{src → dist}/utilities/index.js +3 -1
  95. package/{src → dist}/utilities/time_date.js +6 -7
  96. package/{src → dist}/utilities/utility_functions.js +2 -2
  97. package/dist/webgl/3d_primitives.js +40 -0
  98. package/{src → dist}/webgl/GeometryBufferCache.js +3 -1
  99. package/{src → dist}/webgl/GeometryBuilder.js +12 -8
  100. package/{src → dist}/webgl/ShaderGenerator.js +79 -82
  101. package/{src → dist}/webgl/ShapeBuilder.js +26 -23
  102. package/dist/webgl/index.js +76 -0
  103. package/{src → dist}/webgl/interaction.js +7 -6
  104. package/dist/webgl/light.js +40 -0
  105. package/{src → dist}/webgl/loading.js +45 -12
  106. package/dist/webgl/material.js +40 -0
  107. package/dist/webgl/p5.Camera.js +40 -0
  108. package/{src → dist}/webgl/p5.DataArray.js +3 -5
  109. package/dist/webgl/p5.Framebuffer.js +40 -0
  110. package/{src → dist}/webgl/p5.Geometry.js +12 -15
  111. package/{src → dist}/webgl/p5.Quat.js +5 -4
  112. package/{src → dist}/webgl/p5.RenderBuffer.js +2 -3
  113. package/dist/webgl/p5.RendererGL.js +40 -0
  114. package/dist/webgl/p5.Shader.js +40 -0
  115. package/dist/webgl/p5.Texture.js +40 -0
  116. package/{src → dist}/webgl/text.js +51 -9
  117. package/lib/p5.esm.js +102 -48
  118. package/lib/p5.js +102 -48
  119. package/lib/p5.min.js +1 -1
  120. package/package.json +17 -16
  121. package/translations/dev.js +6 -6
  122. package/translations/index.js +1 -1
  123. package/src/README.md +0 -27
  124. package/src/accessibility/index.js +0 -13
  125. package/src/app.js +0 -61
  126. package/src/color/index.js +0 -9
  127. package/src/color/p5.Color.culori.js +0 -66
  128. package/src/color/p5.Color.js +0 -851
  129. package/src/core/README.md +0 -91
  130. package/src/core/friendly_errors/index.js +0 -13
  131. package/src/core/friendly_errors/param_validator.js +0 -561
  132. package/src/core/init.js +0 -58
  133. package/src/core/internationalization.js +0 -195
  134. package/src/core/legacy.js +0 -29
  135. package/src/core/main.js +0 -689
  136. package/src/core/noop.js +0 -1
  137. package/src/core/p5.Graphics.js +0 -696
  138. package/src/core/p5.Renderer.js +0 -408
  139. package/src/core/reference.js +0 -2060
  140. package/src/core/rendering.js +0 -697
  141. package/src/dom/index.js +0 -11
  142. package/src/image/const.js +0 -6
  143. package/src/image/image.js +0 -731
  144. package/src/image/index.js +0 -15
  145. package/src/image/loading_displaying.js +0 -1431
  146. package/src/io/files.js +0 -2210
  147. package/src/io/index.js +0 -11
  148. package/src/math/README.md +0 -40
  149. package/src/type/index.js +0 -9
  150. package/src/webgl/3d_primitives.js +0 -2741
  151. package/src/webgl/index.js +0 -37
  152. package/src/webgl/light.js +0 -1851
  153. package/src/webgl/material.js +0 -3854
  154. package/src/webgl/p5.Camera.js +0 -4010
  155. package/src/webgl/p5.Framebuffer.js +0 -1865
  156. package/src/webgl/p5.RendererGL.js +0 -2867
  157. package/src/webgl/p5.Shader.js +0 -1505
  158. package/src/webgl/p5.Texture.js +0 -541
  159. package/src/webgl/shaders/basic.frag +0 -6
  160. package/src/webgl/shaders/filters/base.frag +0 -22
  161. package/src/webgl/shaders/filters/base.vert +0 -19
  162. package/src/webgl/shaders/filters/blur.frag +0 -60
  163. package/src/webgl/shaders/filters/default.vert +0 -18
  164. package/src/webgl/shaders/filters/dilate.frag +0 -39
  165. package/src/webgl/shaders/filters/erode.frag +0 -39
  166. package/src/webgl/shaders/filters/gray.frag +0 -16
  167. package/src/webgl/shaders/filters/invert.frag +0 -15
  168. package/src/webgl/shaders/filters/opaque.frag +0 -12
  169. package/src/webgl/shaders/filters/posterize.frag +0 -29
  170. package/src/webgl/shaders/filters/threshold.frag +0 -23
  171. package/src/webgl/shaders/font.frag +0 -216
  172. package/src/webgl/shaders/font.vert +0 -44
  173. package/src/webgl/shaders/imageLight.vert +0 -33
  174. package/src/webgl/shaders/imageLightDiffused.frag +0 -82
  175. package/src/webgl/shaders/imageLightSpecular.frag +0 -134
  176. package/src/webgl/shaders/light.vert +0 -37
  177. package/src/webgl/shaders/light_texture.frag +0 -26
  178. package/src/webgl/shaders/lighting.glsl +0 -227
  179. package/src/webgl/shaders/line.frag +0 -74
  180. package/src/webgl/shaders/line.vert +0 -294
  181. package/src/webgl/shaders/normal.frag +0 -6
  182. package/src/webgl/shaders/normal.vert +0 -72
  183. package/src/webgl/shaders/phong.frag +0 -84
  184. package/src/webgl/shaders/phong.vert +0 -87
  185. package/src/webgl/shaders/point.frag +0 -29
  186. package/src/webgl/shaders/point.vert +0 -19
  187. package/src/webgl/shaders/sphereMapping.frag +0 -26
  188. package/src/webgl/shaders/webgl2Compatibility.glsl +0 -34
@@ -1,2741 +0,0 @@
1
- /**
2
- * @module Shape
3
- * @submodule 3D Primitives
4
- * @for p5
5
- * @requires core
6
- * @requires p5.Geometry
7
- */
8
-
9
- import * as constants from '../core/constants';
10
- import { RendererGL } from './p5.RendererGL';
11
- import { Vector } from '../math/p5.Vector';
12
- import { Geometry } from './p5.Geometry';
13
- import { Matrix } from '../math/p5.Matrix';
14
-
15
- function primitives3D(p5, fn){
16
- /**
17
- * Sets the stroke rendering mode to balance performance and visual features when drawing lines.
18
- *
19
- * `strokeMode()` offers two modes:
20
- *
21
- * - `SIMPLE`: Optimizes for speed by disabling caps, joins, and stroke color features.
22
- * Use this mode for faster line rendering when these visual details are unnecessary.
23
- * - `FULL`: Enables caps, joins, and stroke color for lines.
24
- * This mode provides enhanced visuals but may reduce performance due to additional processing.
25
- *
26
- * Choose the mode that best suits your application's needs to either improve rendering speed or enhance visual quality.
27
- *
28
- * @method strokeMode
29
- * @param {String} mode - The stroke mode to set. Possible values are:
30
- * - `'SIMPLE'`: Fast rendering without caps, joins, or stroke color.
31
- * - `'FULL'`: Detailed rendering with caps, joins, and stroke color.
32
- *
33
- * @example
34
- * <div>
35
- * <code>
36
- * function setup() {
37
- * createCanvas(300, 300, WEBGL);
38
- * describe('A sphere with red stroke and a red, wavy line on a gray background. The wavy line have caps, joins and colors.');
39
- * }
40
- *
41
- * function draw() {
42
- * background(128);
43
- * strokeMode(FULL); // Enables detailed rendering with caps, joins, and stroke color.
44
- * push();
45
- * strokeWeight(1);
46
- * translate(0, -50, 0);
47
- * sphere(50);
48
- * pop();
49
- * orbitControl();
50
- *
51
- * noFill();
52
- * strokeWeight(15);
53
- * stroke('red');
54
- * beginShape();
55
- * bezierOrder(2); // Sets the order of the Bezier curve.
56
- * bezierVertex(80, 80);
57
- * bezierVertex(50, -40);
58
- * bezierVertex(-80, 80);
59
- * endShape();
60
- * }
61
- * </code>
62
- * </div>
63
- *
64
- * <div>
65
- * <code>
66
- * function setup() {
67
- * createCanvas(300, 300, WEBGL);
68
- * describe('A sphere with red stroke and a wavy line without full curve decorations without caps and color on a gray background.');
69
- * }
70
- *
71
- * function draw() {
72
- * background(128);
73
- * strokeMode(SIMPLE); // Simplifies stroke rendering for better performance.
74
- *
75
- * // Draw sphere
76
- * push();
77
- * strokeWeight(1);
78
- * translate(0, -50, 0);
79
- * sphere(50);
80
- * pop();
81
- * orbitControl();
82
- *
83
- * // Draw modified wavy red line
84
- * noFill();
85
- * strokeWeight(15);
86
- * stroke('red');
87
- * beginShape();
88
- * bezierOrder(2); // Sets the order of the Bezier curve.
89
- * bezierVertex(80, 80);
90
- * bezierVertex(50, -40);
91
- * bezierVertex(-80, 80);
92
- * endShape();
93
- * }
94
- * </code>
95
- * </div>
96
- */
97
-
98
- fn.strokeMode = function (mode) {
99
- if (mode === undefined) {
100
- return this._renderer._simpleLines ? constants.SIMPLE : constants.FULL;
101
- } else if (mode === constants.SIMPLE) {
102
- this._renderer._simpleLines = true;
103
- } else if (mode === constants.FULL) {
104
- this._renderer._simpleLines = false;
105
- } else {
106
- throw Error('no such parameter');
107
- }
108
- }
109
- /**
110
- * Creates a custom <a href="#/p5.Geometry">p5.Geometry</a> object from
111
- * simpler 3D shapes.
112
- *
113
- * `buildGeometry()` helps with creating complex 3D shapes from simpler ones
114
- * such as <a href="#/p5/sphere">sphere()</a>. It can help to make sketches
115
- * more performant. For example, if a complex 3D shape doesn’t change while a
116
- * sketch runs, then it can be created with `buildGeometry()`. Creating a
117
- * <a href="#/p5.Geometry">p5.Geometry</a> object once and then drawing it
118
- * will run faster than repeatedly drawing the individual pieces.
119
- *
120
- * The parameter, `callback`, is a function with the drawing instructions for
121
- * the new <a href="#/p5.Geometry">p5.Geometry</a> object. It will be called
122
- * once to create the new 3D shape.
123
- *
124
- * See <a href="#/p5/beginGeometry">beginGeometry()</a> and
125
- * <a href="#/p5/endGeometry">endGeometry()</a> for another way to build 3D
126
- * shapes.
127
- *
128
- * Note: `buildGeometry()` can only be used in WebGL mode.
129
- *
130
- * @method buildGeometry
131
- * @param {Function} callback function that draws the shape.
132
- * @returns {p5.Geometry} new 3D shape.
133
- *
134
- * @example
135
- * <div>
136
- * <code>
137
- * // Click and drag the mouse to view the scene from different angles.
138
- *
139
- * let shape;
140
- *
141
- * function setup() {
142
- * createCanvas(100, 100, WEBGL);
143
- *
144
- * // Create the p5.Geometry object.
145
- * shape = buildGeometry(createShape);
146
- *
147
- * describe('A white cone drawn on a gray background.');
148
- * }
149
- *
150
- * function draw() {
151
- * background(50);
152
- *
153
- * // Enable orbiting with the mouse.
154
- * orbitControl();
155
- *
156
- * // Turn on the lights.
157
- * lights();
158
- *
159
- * // Style the p5.Geometry object.
160
- * noStroke();
161
- *
162
- * // Draw the p5.Geometry object.
163
- * model(shape);
164
- * }
165
- *
166
- * // Create p5.Geometry object from a single cone.
167
- * function createShape() {
168
- * cone();
169
- * }
170
- * </code>
171
- * </div>
172
- *
173
- * <div>
174
- * <code>
175
- * // Click and drag the mouse to view the scene from different angles.
176
- *
177
- * let shape;
178
- *
179
- * function setup() {
180
- * createCanvas(100, 100, WEBGL);
181
- *
182
- * // Create the arrow.
183
- * shape = buildGeometry(createArrow);
184
- *
185
- * describe('A white arrow drawn on a gray background.');
186
- * }
187
- *
188
- * function draw() {
189
- * background(50);
190
- *
191
- * // Enable orbiting with the mouse.
192
- * orbitControl();
193
- *
194
- * // Turn on the lights.
195
- * lights();
196
- *
197
- * // Style the arrow.
198
- * noStroke();
199
- *
200
- * // Draw the arrow.
201
- * model(shape);
202
- * }
203
- *
204
- * function createArrow() {
205
- * // Add shapes to the p5.Geometry object.
206
- * push();
207
- * rotateX(PI);
208
- * cone(10);
209
- * translate(0, -10, 0);
210
- * cylinder(3, 20);
211
- * pop();
212
- * }
213
- * </code>
214
- * </div>
215
- *
216
- * <div>
217
- * <code>
218
- * // Click and drag the mouse to view the scene from different angles.
219
- *
220
- * let shape;
221
- *
222
- * function setup() {
223
- * createCanvas(100, 100, WEBGL);
224
- *
225
- * // Create the p5.Geometry object.
226
- * shape = buildGeometry(createArrow);
227
- *
228
- * describe('Two white arrows drawn on a gray background. The arrow on the right rotates slowly.');
229
- * }
230
- *
231
- * function draw() {
232
- * background(50);
233
- *
234
- * // Enable orbiting with the mouse.
235
- * orbitControl();
236
- *
237
- * // Turn on the lights.
238
- * lights();
239
- *
240
- * // Style the arrows.
241
- * noStroke();
242
- *
243
- * // Draw the p5.Geometry object.
244
- * model(shape);
245
- *
246
- * // Translate and rotate the coordinate system.
247
- * translate(30, 0, 0);
248
- * rotateZ(frameCount * 0.01);
249
- *
250
- * // Draw the p5.Geometry object again.
251
- * model(shape);
252
- * }
253
- *
254
- * function createArrow() {
255
- * // Add shapes to the p5.Geometry object.
256
- * push();
257
- * rotateX(PI);
258
- * cone(10);
259
- * translate(0, -10, 0);
260
- * cylinder(3, 20);
261
- * pop();
262
- * }
263
- * </code>
264
- * </div>
265
- *
266
- * <div>
267
- * <code>
268
- * // Click and drag the mouse to view the scene from different angles.
269
- *
270
- * let button;
271
- * let particles;
272
- *
273
- * function setup() {
274
- * createCanvas(100, 100, WEBGL);
275
- *
276
- * // Create a button to reset the particle system.
277
- * button = createButton('Reset');
278
- *
279
- * // Call resetModel() when the user presses the button.
280
- * button.mousePressed(resetModel);
281
- *
282
- * // Add the original set of particles.
283
- * resetModel();
284
- *
285
- * describe('A set of white spheres on a gray background. The spheres are positioned randomly. Their positions reset when the user presses the Reset button.');
286
- * }
287
- *
288
- * function draw() {
289
- * background(50);
290
- *
291
- * // Enable orbiting with the mouse.
292
- * orbitControl();
293
- *
294
- * // Turn on the lights.
295
- * lights();
296
- *
297
- * // Style the particles.
298
- * noStroke();
299
- *
300
- * // Draw the particles.
301
- * model(particles);
302
- * }
303
- *
304
- * function resetModel() {
305
- * // If the p5.Geometry object has already been created,
306
- * // free those resources.
307
- * if (particles) {
308
- * freeGeometry(particles);
309
- * }
310
- *
311
- * // Create a new p5.Geometry object with random spheres.
312
- * particles = buildGeometry(createParticles);
313
- * }
314
- *
315
- * function createParticles() {
316
- * for (let i = 0; i < 60; i += 1) {
317
- * // Calculate random coordinates.
318
- * let x = randomGaussian(0, 20);
319
- * let y = randomGaussian(0, 20);
320
- * let z = randomGaussian(0, 20);
321
- *
322
- * push();
323
- * // Translate to the particle's coordinates.
324
- * translate(x, y, z);
325
- * // Draw the particle.
326
- * sphere(5);
327
- * pop();
328
- * }
329
- * }
330
- * </code>
331
- * </div>
332
- */
333
- fn.buildGeometry = function(callback) {
334
- return this._renderer.buildGeometry(callback);
335
- };
336
-
337
- /**
338
- * Clears a <a href="#/p5.Geometry">p5.Geometry</a> object from the graphics
339
- * processing unit (GPU) memory.
340
- *
341
- * <a href="#/p5.Geometry">p5.Geometry</a> objects can contain lots of data
342
- * about their vertices, surface normals, colors, and so on. Complex 3D shapes
343
- * can use lots of memory which is a limited resource in many GPUs. Calling
344
- * `freeGeometry()` can improve performance by freeing a
345
- * <a href="#/p5.Geometry">p5.Geometry</a> object’s resources from GPU memory.
346
- * `freeGeometry()` works with <a href="#/p5.Geometry">p5.Geometry</a> objects
347
- * created with <a href="#/p5/beginGeometry">beginGeometry()</a> and
348
- * <a href="#/p5/endGeometry">endGeometry()</a>,
349
- * <a href="#/p5/buildGeometry">buildGeometry()</a>, and
350
- * <a href="#/p5/loadModel">loadModel()</a>.
351
- *
352
- * The parameter, `geometry`, is the <a href="#/p5.Geometry">p5.Geometry</a>
353
- * object to be freed.
354
- *
355
- * Note: A <a href="#/p5.Geometry">p5.Geometry</a> object can still be drawn
356
- * after its resources are cleared from GPU memory. It may take longer to draw
357
- * the first time it’s redrawn.
358
- *
359
- * Note: `freeGeometry()` can only be used in WebGL mode.
360
- *
361
- * @method freeGeometry
362
- * @param {p5.Geometry} geometry 3D shape whose resources should be freed.
363
- *
364
- * @example
365
- * <div>
366
- * <code>
367
- * function setup() {
368
- * createCanvas(100, 100, WEBGL);
369
- *
370
- * background(200);
371
- *
372
- * // Create a p5.Geometry object.
373
- * beginGeometry();
374
- * cone();
375
- * let shape = endGeometry();
376
- *
377
- * // Draw the shape.
378
- * model(shape);
379
- *
380
- * // Free the shape's resources.
381
- * freeGeometry(shape);
382
- * }
383
- * </code>
384
- * </div>
385
- *
386
- * <div>
387
- * <code>
388
- * // Click and drag the mouse to view the scene from different angles.
389
- *
390
- * let button;
391
- * let particles;
392
- *
393
- * function setup() {
394
- * createCanvas(100, 100, WEBGL);
395
- *
396
- * // Create a button to reset the particle system.
397
- * button = createButton('Reset');
398
- *
399
- * // Call resetModel() when the user presses the button.
400
- * button.mousePressed(resetModel);
401
- *
402
- * // Add the original set of particles.
403
- * resetModel();
404
- * }
405
- *
406
- * function draw() {
407
- * background(50);
408
- *
409
- * // Enable orbiting with the mouse.
410
- * orbitControl();
411
- *
412
- * // Turn on the lights.
413
- * lights();
414
- *
415
- * // Style the particles.
416
- * noStroke();
417
- *
418
- * // Draw the particles.
419
- * model(particles);
420
- * }
421
- *
422
- * function resetModel() {
423
- * // If the p5.Geometry object has already been created,
424
- * // free those resources.
425
- * if (particles) {
426
- * freeGeometry(particles);
427
- * }
428
- *
429
- * // Create a new p5.Geometry object with random spheres.
430
- * particles = buildGeometry(createParticles);
431
- * }
432
- *
433
- * function createParticles() {
434
- * for (let i = 0; i < 60; i += 1) {
435
- * // Calculate random coordinates.
436
- * let x = randomGaussian(0, 20);
437
- * let y = randomGaussian(0, 20);
438
- * let z = randomGaussian(0, 20);
439
- *
440
- * push();
441
- * // Translate to the particle's coordinates.
442
- * translate(x, y, z);
443
- * // Draw the particle.
444
- * sphere(5);
445
- * pop();
446
- * }
447
- * }
448
- * </code>
449
- * </div>
450
- */
451
- fn.freeGeometry = function(geometry) {
452
- this._renderer.geometryBufferCache.freeBuffers(geometry.gid);
453
- };
454
-
455
- /**
456
- * Draws a plane.
457
- *
458
- * A plane is a four-sided, flat shape with every angle measuring 90˚. It’s
459
- * similar to a rectangle and offers advanced drawing features in WebGL mode.
460
- *
461
- * The first parameter, `width`, is optional. If a `Number` is passed, as in
462
- * `plane(20)`, it sets the plane’s width and height. By default, `width` is
463
- * 50.
464
- *
465
- * The second parameter, `height`, is also optional. If a `Number` is passed,
466
- * as in `plane(20, 30)`, it sets the plane’s height. By default, `height` is
467
- * set to the plane’s `width`.
468
- *
469
- * The third parameter, `detailX`, is also optional. If a `Number` is passed,
470
- * as in `plane(20, 30, 5)` it sets the number of triangle subdivisions to use
471
- * along the x-axis. All 3D shapes are made by connecting triangles to form
472
- * their surfaces. By default, `detailX` is 1.
473
- *
474
- * The fourth parameter, `detailY`, is also optional. If a `Number` is passed,
475
- * as in `plane(20, 30, 5, 7)` it sets the number of triangle subdivisions to
476
- * use along the y-axis. All 3D shapes are made by connecting triangles to
477
- * form their surfaces. By default, `detailY` is 1.
478
- *
479
- * Note: `plane()` can only be used in WebGL mode.
480
- *
481
- * @method plane
482
- * @param {Number} [width] width of the plane.
483
- * @param {Number} [height] height of the plane.
484
- * @param {Integer} [detailX] number of triangle subdivisions along the x-axis.
485
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis.
486
- * @chainable
487
- *
488
- * @example
489
- * <div>
490
- * <code>
491
- * // Click and drag the mouse to view the scene from different angles.
492
- *
493
- * function setup() {
494
- * createCanvas(100, 100, WEBGL);
495
- *
496
- * describe('A white plane on a gray background.');
497
- * }
498
- *
499
- * function draw() {
500
- * background(200);
501
- *
502
- * // Enable orbiting with the mouse.
503
- * orbitControl();
504
- *
505
- * // Draw the plane.
506
- * plane();
507
- * }
508
- * </code>
509
- * </div>
510
- *
511
- * <div>
512
- * <code>
513
- * // Click and drag the mouse to view the scene from different angles.
514
- *
515
- * function setup() {
516
- * createCanvas(100, 100, WEBGL);
517
- *
518
- * describe('A white plane on a gray background.');
519
- * }
520
- *
521
- * function draw() {
522
- * background(200);
523
- *
524
- * // Enable orbiting with the mouse.
525
- * orbitControl();
526
- *
527
- * // Draw the plane.
528
- * // Set its width and height to 30.
529
- * plane(30);
530
- * }
531
- * </code>
532
- * </div>
533
- *
534
- * <div>
535
- * <code>
536
- * // Click and drag the mouse to view the scene from different angles.
537
- *
538
- * function setup() {
539
- * createCanvas(100, 100, WEBGL);
540
- *
541
- * describe('A white plane on a gray background.');
542
- * }
543
- *
544
- * function draw() {
545
- * background(200);
546
- *
547
- * // Enable orbiting with the mouse.
548
- * orbitControl();
549
- *
550
- * // Draw the plane.
551
- * // Set its width to 30 and height to 50.
552
- * plane(30, 50);
553
- * }
554
- * </code>
555
- * </div>
556
- */
557
- fn.plane = function(
558
- width = 50,
559
- height = width,
560
- detailX = 1,
561
- detailY = 1
562
- ) {
563
- this._assert3d('plane');
564
- // p5._validateParameters('plane', arguments);
565
-
566
- this._renderer.plane(width, height, detailX, detailY);
567
- return this;
568
- };
569
-
570
- /**
571
- * Draws a box (rectangular prism).
572
- *
573
- * A box is a 3D shape with six faces. Each face makes a 90˚ with four
574
- * neighboring faces.
575
- *
576
- * The first parameter, `width`, is optional. If a `Number` is passed, as in
577
- * `box(20)`, it sets the box’s width and height. By default, `width` is 50.
578
- *
579
- * The second parameter, `height`, is also optional. If a `Number` is passed,
580
- * as in `box(20, 30)`, it sets the box’s height. By default, `height` is set
581
- * to the box’s `width`.
582
- *
583
- * The third parameter, `depth`, is also optional. If a `Number` is passed, as
584
- * in `box(20, 30, 40)`, it sets the box’s depth. By default, `depth` is set
585
- * to the box’s `height`.
586
- *
587
- * The fourth parameter, `detailX`, is also optional. If a `Number` is passed,
588
- * as in `box(20, 30, 40, 5)`, it sets the number of triangle subdivisions to
589
- * use along the x-axis. All 3D shapes are made by connecting triangles to
590
- * form their surfaces. By default, `detailX` is 1.
591
- *
592
- * The fifth parameter, `detailY`, is also optional. If a number is passed, as
593
- * in `box(20, 30, 40, 5, 7)`, it sets the number of triangle subdivisions to
594
- * use along the y-axis. All 3D shapes are made by connecting triangles to
595
- * form their surfaces. By default, `detailY` is 1.
596
- *
597
- * Note: `box()` can only be used in WebGL mode.
598
- *
599
- * @method box
600
- * @param {Number} [width] width of the box.
601
- * @param {Number} [height] height of the box.
602
- * @param {Number} [depth] depth of the box.
603
- * @param {Integer} [detailX] number of triangle subdivisions along the x-axis.
604
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis.
605
- * @chainable
606
- *
607
- * @example
608
- * <div>
609
- * <code>
610
- * // Click and drag the mouse to view the scene from different angles.
611
- *
612
- * function setup() {
613
- * createCanvas(100, 100, WEBGL);
614
- *
615
- * describe('A white box on a gray background.');
616
- * }
617
- *
618
- * function draw() {
619
- * background(200);
620
- *
621
- * // Enable orbiting with the mouse.
622
- * orbitControl();
623
- *
624
- * // Draw the box.
625
- * box();
626
- * }
627
- * </code>
628
- * </div>
629
- *
630
- * <div>
631
- * <code>
632
- * // Click and drag the mouse to view the scene from different angles.
633
- *
634
- * function setup() {
635
- * createCanvas(100, 100, WEBGL);
636
- *
637
- * describe('A white box on a gray background.');
638
- * }
639
- *
640
- * function draw() {
641
- * background(200);
642
- *
643
- * // Enable orbiting with the mouse.
644
- * orbitControl();
645
- *
646
- * // Draw the box.
647
- * // Set its width and height to 30.
648
- * box(30);
649
- * }
650
- * </code>
651
- * </div>
652
- *
653
- * <div>
654
- * <code>
655
- * // Click and drag the mouse to view the scene from different angles.
656
- *
657
- * function setup() {
658
- * createCanvas(100, 100, WEBGL);
659
- *
660
- * describe('A white box on a gray background.');
661
- * }
662
- *
663
- * function draw() {
664
- * background(200);
665
- *
666
- * // Enable orbiting with the mouse.
667
- * orbitControl();
668
- *
669
- * // Draw the box.
670
- * // Set its width to 30 and height to 50.
671
- * box(30, 50);
672
- * }
673
- * </code>
674
- * </div>
675
- *
676
- * <div>
677
- * <code>
678
- * // Click and drag the mouse to view the scene from different angles.
679
- *
680
- * function setup() {
681
- * createCanvas(100, 100, WEBGL);
682
- *
683
- * describe('A white box on a gray background.');
684
- * }
685
- *
686
- * function draw() {
687
- * background(200);
688
- *
689
- * // Enable orbiting with the mouse.
690
- * orbitControl();
691
- *
692
- * // Draw the box.
693
- * // Set its width to 30, height to 50, and depth to 10.
694
- * box(30, 50, 10);
695
- * }
696
- * </code>
697
- * </div>
698
- */
699
- fn.box = function(width, height, depth, detailX, detailY) {
700
- this._assert3d('box');
701
- // p5._validateParameters('box', arguments);
702
-
703
- this._renderer.box(width, height, depth, detailX, detailY);
704
-
705
- return this;
706
- };
707
-
708
- /**
709
- * Draws a sphere.
710
- *
711
- * A sphere is a 3D shape with triangular faces that connect to form a round
712
- * surface. Spheres with few faces look like crystals. Spheres with many faces
713
- * have smooth surfaces and look like balls.
714
- *
715
- * The first parameter, `radius`, is optional. If a `Number` is passed, as in
716
- * `sphere(20)`, it sets the radius of the sphere. By default, `radius` is 50.
717
- *
718
- * The second parameter, `detailX`, is also optional. If a `Number` is passed,
719
- * as in `sphere(20, 5)`, it sets the number of triangle subdivisions to use
720
- * along the x-axis. All 3D shapes are made by connecting triangles to form
721
- * their surfaces. By default, `detailX` is 24.
722
- *
723
- * The third parameter, `detailY`, is also optional. If a `Number` is passed,
724
- * as in `sphere(20, 5, 2)`, it sets the number of triangle subdivisions to
725
- * use along the y-axis. All 3D shapes are made by connecting triangles to
726
- * form their surfaces. By default, `detailY` is 16.
727
- *
728
- * Note: `sphere()` can only be used in WebGL mode.
729
- *
730
- * @method sphere
731
- * @param {Number} [radius] radius of the sphere. Defaults to 50.
732
- * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. Defaults to 24.
733
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16.
734
- *
735
- * @chainable
736
- * @example
737
- * <div>
738
- * <code>
739
- * // Click and drag the mouse to view the scene from different angles.
740
- *
741
- * function setup() {
742
- * createCanvas(100, 100, WEBGL);
743
- *
744
- * describe('A white sphere on a gray background.');
745
- * }
746
- *
747
- * function draw() {
748
- * background(200);
749
- *
750
- * // Enable orbiting with the mouse.
751
- * orbitControl();
752
- *
753
- * // Draw the sphere.
754
- * sphere();
755
- * }
756
- * </code>
757
- * </div>
758
- *
759
- * <div>
760
- * <code>
761
- * // Click and drag the mouse to view the scene from different angles.
762
- *
763
- * function setup() {
764
- * createCanvas(100, 100, WEBGL);
765
- *
766
- * describe('A white sphere on a gray background.');
767
- * }
768
- *
769
- * function draw() {
770
- * background(200);
771
- *
772
- * // Enable orbiting with the mouse.
773
- * orbitControl();
774
- *
775
- * // Draw the sphere.
776
- * // Set its radius to 30.
777
- * sphere(30);
778
- * }
779
- * </code>
780
- * </div>
781
- *
782
- * <div>
783
- * <code>
784
- * // Click and drag the mouse to view the scene from different angles.
785
- *
786
- * function setup() {
787
- * createCanvas(100, 100, WEBGL);
788
- *
789
- * describe('A white sphere on a gray background.');
790
- * }
791
- *
792
- * function draw() {
793
- * background(200);
794
- *
795
- * // Enable orbiting with the mouse.
796
- * orbitControl();
797
- *
798
- * // Draw the sphere.
799
- * // Set its radius to 30.
800
- * // Set its detailX to 6.
801
- * sphere(30, 6);
802
- * }
803
- * </code>
804
- * </div>
805
- *
806
- * <div>
807
- * <code>
808
- * // Click and drag the mouse to view the scene from different angles.
809
- *
810
- * function setup() {
811
- * createCanvas(100, 100, WEBGL);
812
- *
813
- * describe('A white sphere on a gray background.');
814
- * }
815
- *
816
- * function draw() {
817
- * background(200);
818
- *
819
- * // Enable orbiting with the mouse.
820
- * orbitControl();
821
- *
822
- * // Draw the sphere.
823
- * // Set its radius to 30.
824
- * // Set its detailX to 24.
825
- * // Set its detailY to 4.
826
- * sphere(30, 24, 4);
827
- * }
828
- * </code>
829
- * </div>
830
- */
831
- fn.sphere = function(radius = 50, detailX = 24, detailY = 16) {
832
- this._assert3d('sphere');
833
- // p5._validateParameters('sphere', arguments);
834
-
835
- this._renderer.sphere(radius, detailX, detailY);
836
-
837
- return this;
838
- };
839
-
840
- /**
841
- * Draws a cylinder.
842
- *
843
- * A cylinder is a 3D shape with triangular faces that connect a flat bottom
844
- * to a flat top. Cylinders with few faces look like boxes. Cylinders with
845
- * many faces have smooth surfaces.
846
- *
847
- * The first parameter, `radius`, is optional. If a `Number` is passed, as in
848
- * `cylinder(20)`, it sets the radius of the cylinder’s base. By default,
849
- * `radius` is 50.
850
- *
851
- * The second parameter, `height`, is also optional. If a `Number` is passed,
852
- * as in `cylinder(20, 30)`, it sets the cylinder’s height. By default,
853
- * `height` is set to the cylinder’s `radius`.
854
- *
855
- * The third parameter, `detailX`, is also optional. If a `Number` is passed,
856
- * as in `cylinder(20, 30, 5)`, it sets the number of edges used to form the
857
- * cylinder's top and bottom. Using more edges makes the top and bottom look
858
- * more like circles. By default, `detailX` is 24.
859
- *
860
- * The fourth parameter, `detailY`, is also optional. If a `Number` is passed,
861
- * as in `cylinder(20, 30, 5, 2)`, it sets the number of triangle subdivisions
862
- * to use along the y-axis, between cylinder's the top and bottom. All 3D
863
- * shapes are made by connecting triangles to form their surfaces. By default,
864
- * `detailY` is 1.
865
- *
866
- * The fifth parameter, `bottomCap`, is also optional. If a `false` is passed,
867
- * as in `cylinder(20, 30, 5, 2, false)` the cylinder’s bottom won’t be drawn.
868
- * By default, `bottomCap` is `true`.
869
- *
870
- * The sixth parameter, `topCap`, is also optional. If a `false` is passed, as
871
- * in `cylinder(20, 30, 5, 2, false, false)` the cylinder’s top won’t be
872
- * drawn. By default, `topCap` is `true`.
873
- *
874
- * Note: `cylinder()` can only be used in WebGL mode.
875
- *
876
- * @method cylinder
877
- * @param {Number} [radius] radius of the cylinder. Defaults to 50.
878
- * @param {Number} [height] height of the cylinder. Defaults to the value of `radius`.
879
- * @param {Integer} [detailX] number of edges along the top and bottom. Defaults to 24.
880
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 1.
881
- * @param {Boolean} [bottomCap] whether to draw the cylinder's bottom. Defaults to `true`.
882
- * @param {Boolean} [topCap] whether to draw the cylinder's top. Defaults to `true`.
883
- * @chainable
884
- *
885
- * @example
886
- * <div>
887
- * <code>
888
- * // Click and drag the mouse to view the scene from different angles.
889
- *
890
- * function setup() {
891
- * createCanvas(100, 100, WEBGL);
892
- *
893
- * describe('A white cylinder on a gray background.');
894
- * }
895
- *
896
- * function draw() {
897
- * background(200);
898
- *
899
- * // Enable orbiting with the mouse.
900
- * orbitControl();
901
- *
902
- * // Draw the cylinder.
903
- * cylinder();
904
- * }
905
- * </code>
906
- * </div>
907
- *
908
- * <div>
909
- * <code>
910
- * // Click and drag the mouse to view the scene from different angles.
911
- *
912
- * function setup() {
913
- * createCanvas(100, 100, WEBGL);
914
- *
915
- * describe('A white cylinder on a gray background.');
916
- * }
917
- *
918
- * function draw() {
919
- * background(200);
920
- *
921
- * // Enable orbiting with the mouse.
922
- * orbitControl();
923
- *
924
- * // Draw the cylinder.
925
- * // Set its radius and height to 30.
926
- * cylinder(30);
927
- * }
928
- * </code>
929
- * </div>
930
- *
931
- * <div>
932
- * <code>
933
- * // Click and drag the mouse to view the scene from different angles.
934
- *
935
- * function setup() {
936
- * createCanvas(100, 100, WEBGL);
937
- *
938
- * describe('A white cylinder on a gray background.');
939
- * }
940
- *
941
- * function draw() {
942
- * background(200);
943
- *
944
- * // Enable orbiting with the mouse.
945
- * orbitControl();
946
- *
947
- * // Draw the cylinder.
948
- * // Set its radius to 30 and height to 50.
949
- * cylinder(30, 50);
950
- * }
951
- * </code>
952
- * </div>
953
- *
954
- * <div>
955
- * <code>
956
- * // Click and drag the mouse to view the scene from different angles.
957
- *
958
- * function setup() {
959
- * createCanvas(100, 100, WEBGL);
960
- *
961
- * describe('A white box on a gray background.');
962
- * }
963
- *
964
- * function draw() {
965
- * background(200);
966
- *
967
- * // Enable orbiting with the mouse.
968
- * orbitControl();
969
- *
970
- * // Draw the cylinder.
971
- * // Set its radius to 30 and height to 50.
972
- * // Set its detailX to 5.
973
- * cylinder(30, 50, 5);
974
- * }
975
- * </code>
976
- * </div>
977
- *
978
- * <div>
979
- * <code>
980
- * // Click and drag the mouse to view the scene from different angles.
981
- *
982
- * function setup() {
983
- * createCanvas(100, 100, WEBGL);
984
- *
985
- * describe('A white cylinder on a gray background.');
986
- * }
987
- *
988
- * function draw() {
989
- * background(200);
990
- *
991
- * // Enable orbiting with the mouse.
992
- * orbitControl();
993
- *
994
- * // Draw the cylinder.
995
- * // Set its radius to 30 and height to 50.
996
- * // Set its detailX to 24 and detailY to 2.
997
- * cylinder(30, 50, 24, 2);
998
- * }
999
- * </code>
1000
- * </div>
1001
- *
1002
- * <div>
1003
- * <code>
1004
- * // Click and drag the mouse to view the scene from different angles.
1005
- *
1006
- * function setup() {
1007
- * createCanvas(100, 100, WEBGL);
1008
- *
1009
- * describe('A white cylinder on a gray background. Its top is missing.');
1010
- * }
1011
- *
1012
- * function draw() {
1013
- * background(200);
1014
- *
1015
- * // Enable orbiting with the mouse.
1016
- * orbitControl();
1017
- *
1018
- * // Draw the cylinder.
1019
- * // Set its radius to 30 and height to 50.
1020
- * // Set its detailX to 24 and detailY to 1.
1021
- * // Don't draw its bottom.
1022
- * cylinder(30, 50, 24, 1, false);
1023
- * }
1024
- * </code>
1025
- * </div>
1026
- *
1027
- * <div>
1028
- * <code>
1029
- * // Click and drag the mouse to view the scene from different angles.
1030
- *
1031
- * function setup() {
1032
- * createCanvas(100, 100, WEBGL);
1033
- *
1034
- * describe('A white cylinder on a gray background. Its top and bottom are missing.');
1035
- * }
1036
- *
1037
- * function draw() {
1038
- * background(200);
1039
- *
1040
- * // Enable orbiting with the mouse.
1041
- * orbitControl();
1042
- *
1043
- * // Draw the cylinder.
1044
- * // Set its radius to 30 and height to 50.
1045
- * // Set its detailX to 24 and detailY to 1.
1046
- * // Don't draw its bottom or top.
1047
- * cylinder(30, 50, 24, 1, false, false);
1048
- * }
1049
- * </code>
1050
- * </div>
1051
- */
1052
- fn.cylinder = function(
1053
- radius = 50,
1054
- height = radius,
1055
- detailX = 24,
1056
- detailY = 1,
1057
- bottomCap = true,
1058
- topCap = true
1059
- ) {
1060
- this._assert3d('cylinder');
1061
- // p5._validateParameters('cylinder', arguments);
1062
-
1063
- this._renderer.cylinder(radius, height, detailX, detailY, bottomCap, topCap);
1064
-
1065
- return this;
1066
- };
1067
-
1068
- /**
1069
- * Draws a cone.
1070
- *
1071
- * A cone is a 3D shape with triangular faces that connect a flat bottom to a
1072
- * single point. Cones with few faces look like pyramids. Cones with many
1073
- * faces have smooth surfaces.
1074
- *
1075
- * The first parameter, `radius`, is optional. If a `Number` is passed, as in
1076
- * `cone(20)`, it sets the radius of the cone’s base. By default, `radius` is
1077
- * 50.
1078
- *
1079
- * The second parameter, `height`, is also optional. If a `Number` is passed,
1080
- * as in `cone(20, 30)`, it sets the cone’s height. By default, `height` is
1081
- * set to the cone’s `radius`.
1082
- *
1083
- * The third parameter, `detailX`, is also optional. If a `Number` is passed,
1084
- * as in `cone(20, 30, 5)`, it sets the number of edges used to form the
1085
- * cone's base. Using more edges makes the base look more like a circle. By
1086
- * default, `detailX` is 24.
1087
- *
1088
- * The fourth parameter, `detailY`, is also optional. If a `Number` is passed,
1089
- * as in `cone(20, 30, 5, 7)`, it sets the number of triangle subdivisions to
1090
- * use along the y-axis connecting the base to the tip. All 3D shapes are made
1091
- * by connecting triangles to form their surfaces. By default, `detailY` is 1.
1092
- *
1093
- * The fifth parameter, `cap`, is also optional. If a `false` is passed, as
1094
- * in `cone(20, 30, 5, 7, false)` the cone’s base won’t be drawn. By default,
1095
- * `cap` is `true`.
1096
- *
1097
- * Note: `cone()` can only be used in WebGL mode.
1098
- *
1099
- * @method cone
1100
- * @param {Number} [radius] radius of the cone's base. Defaults to 50.
1101
- * @param {Number} [height] height of the cone. Defaults to the value of `radius`.
1102
- * @param {Integer} [detailX] number of edges used to draw the base. Defaults to 24.
1103
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 1.
1104
- * @param {Boolean} [cap] whether to draw the cone's base. Defaults to `true`.
1105
- * @chainable
1106
- *
1107
- * @example
1108
- * <div>
1109
- * <code>
1110
- * // Click and drag the mouse to view the scene from different angles.
1111
- *
1112
- * function setup() {
1113
- * createCanvas(100, 100, WEBGL);
1114
- *
1115
- * describe('A white cone on a gray background.');
1116
- * }
1117
- *
1118
- * function draw() {
1119
- * background(200);
1120
- *
1121
- * // Enable orbiting with the mouse.
1122
- * orbitControl();
1123
- *
1124
- * // Draw the cone.
1125
- * cone();
1126
- * }
1127
- * </code>
1128
- * </div>
1129
- *
1130
- * <div>
1131
- * <code>
1132
- * // Click and drag the mouse to view the scene from different angles.
1133
- *
1134
- * function setup() {
1135
- * createCanvas(100, 100, WEBGL);
1136
- *
1137
- * describe('A white cone on a gray background.');
1138
- * }
1139
- *
1140
- * function draw() {
1141
- * background(200);
1142
- *
1143
- * // Enable orbiting with the mouse.
1144
- * orbitControl();
1145
- *
1146
- * // Draw the cone.
1147
- * // Set its radius and height to 30.
1148
- * cone(30);
1149
- * }
1150
- * </code>
1151
- * </div>
1152
- *
1153
- * <div>
1154
- * <code>
1155
- * // Click and drag the mouse to view the scene from different angles.
1156
- *
1157
- * function setup() {
1158
- * createCanvas(100, 100, WEBGL);
1159
- *
1160
- * describe('A white cone on a gray background.');
1161
- * }
1162
- *
1163
- * function draw() {
1164
- * background(200);
1165
- *
1166
- * // Enable orbiting with the mouse.
1167
- * orbitControl();
1168
- *
1169
- * // Draw the cone.
1170
- * // Set its radius to 30 and height to 50.
1171
- * cone(30, 50);
1172
- * }
1173
- * </code>
1174
- * </div>
1175
- *
1176
- * <div>
1177
- * <code>
1178
- * // Click and drag the mouse to view the scene from different angles.
1179
- *
1180
- * function setup() {
1181
- * createCanvas(100, 100, WEBGL);
1182
- *
1183
- * describe('A white cone on a gray background.');
1184
- * }
1185
- *
1186
- * function draw() {
1187
- * background(200);
1188
- *
1189
- * // Enable orbiting with the mouse.
1190
- * orbitControl();
1191
- *
1192
- * // Draw the cone.
1193
- * // Set its radius to 30 and height to 50.
1194
- * // Set its detailX to 5.
1195
- * cone(30, 50, 5);
1196
- * }
1197
- * </code>
1198
- * </div>
1199
- *
1200
- * <div>
1201
- * <code>
1202
- * // Click and drag the mouse to view the scene from different angles.
1203
- *
1204
- * function setup() {
1205
- * createCanvas(100, 100, WEBGL);
1206
- *
1207
- * describe('A white pyramid on a gray background.');
1208
- * }
1209
- *
1210
- * function draw() {
1211
- * background(200);
1212
- *
1213
- * // Enable orbiting with the mouse.
1214
- * orbitControl();
1215
- *
1216
- * // Draw the cone.
1217
- * // Set its radius to 30 and height to 50.
1218
- * // Set its detailX to 5.
1219
- * cone(30, 50, 5);
1220
- * }
1221
- * </code>
1222
- * </div>
1223
- *
1224
- * <div>
1225
- * <code>
1226
- * // Click and drag the mouse to view the scene from different angles.
1227
- *
1228
- * function setup() {
1229
- * createCanvas(100, 100, WEBGL);
1230
- *
1231
- * describe('A white cone on a gray background.');
1232
- * }
1233
- *
1234
- * function draw() {
1235
- * background(200);
1236
- *
1237
- * // Enable orbiting with the mouse.
1238
- * orbitControl();
1239
- *
1240
- * // Draw the cone.
1241
- * // Set its radius to 30 and height to 50.
1242
- * // Set its detailX to 24 and detailY to 2.
1243
- * cone(30, 50, 24, 2);
1244
- * }
1245
- * </code>
1246
- * </div>
1247
- *
1248
- * <div>
1249
- * <code>
1250
- * // Click and drag the mouse to view the scene from different angles.
1251
- *
1252
- * function setup() {
1253
- * createCanvas(100, 100, WEBGL);
1254
- *
1255
- * describe('A white cone on a gray background. Its base is missing.');
1256
- * }
1257
- *
1258
- * function draw() {
1259
- * background(200);
1260
- *
1261
- * // Enable orbiting with the mouse.
1262
- * orbitControl();
1263
- *
1264
- * // Draw the cone.
1265
- * // Set its radius to 30 and height to 50.
1266
- * // Set its detailX to 24 and detailY to 1.
1267
- * // Don't draw its base.
1268
- * cone(30, 50, 24, 1, false);
1269
- * }
1270
- * </code>
1271
- * </div>
1272
- */
1273
- fn.cone = function(
1274
- radius = 50,
1275
- height = radius,
1276
- detailX = 24,
1277
- detailY = 1,
1278
- cap = true
1279
- ) {
1280
- this._assert3d('cone');
1281
- // p5._validateParameters('cone', arguments);
1282
-
1283
- this._renderer.cone(radius, height, detailX, detailY, cap);
1284
-
1285
- return this;
1286
- };
1287
-
1288
- /**
1289
- * Draws an ellipsoid.
1290
- *
1291
- * An ellipsoid is a 3D shape with triangular faces that connect to form a
1292
- * round surface. Ellipsoids with few faces look like crystals. Ellipsoids
1293
- * with many faces have smooth surfaces and look like eggs. `ellipsoid()`
1294
- * defines a shape by its radii. This is different from
1295
- * <a href="#/p5/ellipse">ellipse()</a> which uses diameters
1296
- * (width and height).
1297
- *
1298
- * The first parameter, `radiusX`, is optional. If a `Number` is passed, as in
1299
- * `ellipsoid(20)`, it sets the radius of the ellipsoid along the x-axis. By
1300
- * default, `radiusX` is 50.
1301
- *
1302
- * The second parameter, `radiusY`, is also optional. If a `Number` is passed,
1303
- * as in `ellipsoid(20, 30)`, it sets the ellipsoid’s radius along the y-axis.
1304
- * By default, `radiusY` is set to the ellipsoid’s `radiusX`.
1305
- *
1306
- * The third parameter, `radiusZ`, is also optional. If a `Number` is passed,
1307
- * as in `ellipsoid(20, 30, 40)`, it sets the ellipsoid’s radius along the
1308
- * z-axis. By default, `radiusZ` is set to the ellipsoid’s `radiusY`.
1309
- *
1310
- * The fourth parameter, `detailX`, is also optional. If a `Number` is passed,
1311
- * as in `ellipsoid(20, 30, 40, 5)`, it sets the number of triangle
1312
- * subdivisions to use along the x-axis. All 3D shapes are made by connecting
1313
- * triangles to form their surfaces. By default, `detailX` is 24.
1314
- *
1315
- * The fifth parameter, `detailY`, is also optional. If a `Number` is passed,
1316
- * as in `ellipsoid(20, 30, 40, 5, 7)`, it sets the number of triangle
1317
- * subdivisions to use along the y-axis. All 3D shapes are made by connecting
1318
- * triangles to form their surfaces. By default, `detailY` is 16.
1319
- *
1320
- * Note: `ellipsoid()` can only be used in WebGL mode.
1321
- *
1322
- * @method ellipsoid
1323
- * @param {Number} [radiusX] radius of the ellipsoid along the x-axis. Defaults to 50.
1324
- * @param {Number} [radiusY] radius of the ellipsoid along the y-axis. Defaults to `radiusX`.
1325
- * @param {Number} [radiusZ] radius of the ellipsoid along the z-axis. Defaults to `radiusY`.
1326
- * @param {Integer} [detailX] number of triangle subdivisions along the x-axis. Defaults to 24.
1327
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16.
1328
- * @chainable
1329
- *
1330
- * @example
1331
- * <div>
1332
- * <code>
1333
- * // Click and drag the mouse to view the scene from different angles.
1334
- *
1335
- * function setup() {
1336
- * createCanvas(100, 100, WEBGL);
1337
- *
1338
- * describe('A white sphere on a gray background.');
1339
- * }
1340
- *
1341
- * function draw() {
1342
- * background(200);
1343
- *
1344
- * // Enable orbiting with the mouse.
1345
- * orbitControl();
1346
- *
1347
- * // Draw the ellipsoid.
1348
- * // Set its radiusX to 30.
1349
- * ellipsoid(30);
1350
- * }
1351
- * </code>
1352
- * </div>
1353
- *
1354
- * <div>
1355
- * <code>
1356
- * // Click and drag the mouse to view the scene from different angles.
1357
- *
1358
- * function setup() {
1359
- * createCanvas(100, 100, WEBGL);
1360
- *
1361
- * describe('A white ellipsoid on a gray background.');
1362
- * }
1363
- *
1364
- * function draw() {
1365
- * background(200);
1366
- *
1367
- * // Enable orbiting with the mouse.
1368
- * orbitControl();
1369
- *
1370
- * // Draw the ellipsoid.
1371
- * // Set its radiusX to 30.
1372
- * // Set its radiusY to 40.
1373
- * ellipsoid(30, 40);
1374
- * }
1375
- * </code>
1376
- * </div>
1377
- *
1378
- * <div>
1379
- * <code>
1380
- * // Click and drag the mouse to view the scene from different angles.
1381
- *
1382
- * function setup() {
1383
- * createCanvas(100, 100, WEBGL);
1384
- *
1385
- * describe('A white ellipsoid on a gray background.');
1386
- * }
1387
- *
1388
- * function draw() {
1389
- * background(200);
1390
- *
1391
- * // Enable orbiting with the mouse.
1392
- * orbitControl();
1393
- *
1394
- * // Draw the ellipsoid.
1395
- * // Set its radiusX to 30.
1396
- * // Set its radiusY to 40.
1397
- * // Set its radiusZ to 50.
1398
- * ellipsoid(30, 40, 50);
1399
- * }
1400
- * </code>
1401
- * </div>
1402
- *
1403
- * <div>
1404
- * <code>
1405
- * // Click and drag the mouse to view the scene from different angles.
1406
- *
1407
- * function setup() {
1408
- * createCanvas(100, 100, WEBGL);
1409
- *
1410
- * describe('A white ellipsoid on a gray background.');
1411
- * }
1412
- *
1413
- * function draw() {
1414
- * background(200);
1415
- *
1416
- * // Enable orbiting with the mouse.
1417
- * orbitControl();
1418
- *
1419
- * // Draw the ellipsoid.
1420
- * // Set its radiusX to 30.
1421
- * // Set its radiusY to 40.
1422
- * // Set its radiusZ to 50.
1423
- * // Set its detailX to 4.
1424
- * ellipsoid(30, 40, 50, 4);
1425
- * }
1426
- * </code>
1427
- * </div>
1428
- *
1429
- * <div>
1430
- * <code>
1431
- * // Click and drag the mouse to view the scene from different angles.
1432
- *
1433
- * function setup() {
1434
- * createCanvas(100, 100, WEBGL);
1435
- *
1436
- * describe('A white ellipsoid on a gray background.');
1437
- * }
1438
- *
1439
- * function draw() {
1440
- * background(200);
1441
- *
1442
- * // Enable orbiting with the mouse.
1443
- * orbitControl();
1444
- *
1445
- * // Draw the ellipsoid.
1446
- * // Set its radiusX to 30.
1447
- * // Set its radiusY to 40.
1448
- * // Set its radiusZ to 50.
1449
- * // Set its detailX to 4.
1450
- * // Set its detailY to 3.
1451
- * ellipsoid(30, 40, 50, 4, 3);
1452
- * }
1453
- * </code>
1454
- * </div>
1455
- */
1456
- fn.ellipsoid = function(
1457
- radiusX = 50,
1458
- radiusY = radiusX,
1459
- radiusZ = radiusX,
1460
- detailX = 24,
1461
- detailY = 16
1462
- ) {
1463
- this._assert3d('ellipsoid');
1464
- // p5._validateParameters('ellipsoid', arguments);
1465
-
1466
- this._renderer.ellipsoid(radiusX, radiusY, radiusZ, detailX, detailY);
1467
-
1468
- return this;
1469
- };
1470
-
1471
- /**
1472
- * Draws a torus.
1473
- *
1474
- * A torus is a 3D shape with triangular faces that connect to form a ring.
1475
- * Toruses with few faces look flattened. Toruses with many faces have smooth
1476
- * surfaces.
1477
- *
1478
- * The first parameter, `radius`, is optional. If a `Number` is passed, as in
1479
- * `torus(30)`, it sets the radius of the ring. By default, `radius` is 50.
1480
- *
1481
- * The second parameter, `tubeRadius`, is also optional. If a `Number` is
1482
- * passed, as in `torus(30, 15)`, it sets the radius of the tube. By default,
1483
- * `tubeRadius` is 10.
1484
- *
1485
- * The third parameter, `detailX`, is also optional. If a `Number` is passed,
1486
- * as in `torus(30, 15, 5)`, it sets the number of edges used to draw the hole
1487
- * of the torus. Using more edges makes the hole look more like a circle. By
1488
- * default, `detailX` is 24.
1489
- *
1490
- * The fourth parameter, `detailY`, is also optional. If a `Number` is passed,
1491
- * as in `torus(30, 15, 5, 7)`, it sets the number of triangle subdivisions to
1492
- * use while filling in the torus’ height. By default, `detailY` is 16.
1493
- *
1494
- * Note: `torus()` can only be used in WebGL mode.
1495
- *
1496
- * @method torus
1497
- * @param {Number} [radius] radius of the torus. Defaults to 50.
1498
- * @param {Number} [tubeRadius] radius of the tube. Defaults to 10.
1499
- * @param {Integer} [detailX] number of edges that form the hole. Defaults to 24.
1500
- * @param {Integer} [detailY] number of triangle subdivisions along the y-axis. Defaults to 16.
1501
- * @chainable
1502
- *
1503
- * @example
1504
- * <div>
1505
- * <code>
1506
- * // Click and drag the mouse to view the scene from different angles.
1507
- *
1508
- * function setup() {
1509
- * createCanvas(100, 100, WEBGL);
1510
- *
1511
- * describe('A white torus on a gray background.');
1512
- * }
1513
- *
1514
- * function draw() {
1515
- * background(200);
1516
- *
1517
- * // Enable orbiting with the mouse.
1518
- * orbitControl();
1519
- *
1520
- * // Draw the torus.
1521
- * torus();
1522
- * }
1523
- * </code>
1524
- * </div>
1525
- *
1526
- * <div>
1527
- * <code>
1528
- * // Click and drag the mouse to view the scene from different angles.
1529
- *
1530
- * function setup() {
1531
- * createCanvas(100, 100, WEBGL);
1532
- *
1533
- * describe('A white torus on a gray background.');
1534
- * }
1535
- *
1536
- * function draw() {
1537
- * background(200);
1538
- *
1539
- * // Enable orbiting with the mouse.
1540
- * orbitControl();
1541
- *
1542
- * // Draw the torus.
1543
- * // Set its radius to 30.
1544
- * torus(30);
1545
- * }
1546
- * </code>
1547
- * </div>
1548
- *
1549
- * <div>
1550
- * <code>
1551
- * // Click and drag the mouse to view the scene from different angles.
1552
- *
1553
- * function setup() {
1554
- * createCanvas(100, 100, WEBGL);
1555
- *
1556
- * describe('A white torus on a gray background.');
1557
- * }
1558
- *
1559
- * function draw() {
1560
- * background(200);
1561
- *
1562
- * // Enable orbiting with the mouse.
1563
- * orbitControl();
1564
- *
1565
- * // Draw the torus.
1566
- * // Set its radius to 30 and tubeRadius to 15.
1567
- * torus(30, 15);
1568
- * }
1569
- * </code>
1570
- * </div>
1571
- *
1572
- * <div>
1573
- * <code>
1574
- * // Click and drag the mouse to view the scene from different angles.
1575
- *
1576
- * function setup() {
1577
- * createCanvas(100, 100, WEBGL);
1578
- *
1579
- * describe('A white torus on a gray background.');
1580
- * }
1581
- *
1582
- * function draw() {
1583
- * background(200);
1584
- *
1585
- * // Enable orbiting with the mouse.
1586
- * orbitControl();
1587
- *
1588
- * // Draw the torus.
1589
- * // Set its radius to 30 and tubeRadius to 15.
1590
- * // Set its detailX to 5.
1591
- * torus(30, 15, 5);
1592
- * }
1593
- * </code>
1594
- * </div>
1595
- *
1596
- * <div>
1597
- * <code>
1598
- * // Click and drag the mouse to view the scene from different angles.
1599
- *
1600
- * function setup() {
1601
- * createCanvas(100, 100, WEBGL);
1602
- *
1603
- * describe('A white torus on a gray background.');
1604
- * }
1605
- *
1606
- * function draw() {
1607
- * background(200);
1608
- *
1609
- * // Enable orbiting with the mouse.
1610
- * orbitControl();
1611
- *
1612
- * // Draw the torus.
1613
- * // Set its radius to 30 and tubeRadius to 15.
1614
- * // Set its detailX to 5.
1615
- * // Set its detailY to 3.
1616
- * torus(30, 15, 5, 3);
1617
- * }
1618
- * </code>
1619
- * </div>
1620
- */
1621
- fn.torus = function(radius, tubeRadius, detailX, detailY) {
1622
- this._assert3d('torus');
1623
- // p5._validateParameters('torus', arguments);
1624
-
1625
- this._renderer.torus(radius, tubeRadius, detailX, detailY);
1626
-
1627
- return this;
1628
- };
1629
-
1630
- ///////////////////////
1631
- /// 2D primitives ///
1632
- ///////////////////////
1633
- //
1634
- // Note: Documentation is not generated on the p5.js website for functions on
1635
- // the p5.RendererGL prototype.
1636
-
1637
- /**
1638
- * Draws a point, a coordinate in space at the dimension of one pixel,
1639
- * given x, y and z coordinates. The color of the point is determined
1640
- * by the current stroke, while the point size is determined by current
1641
- * stroke weight.
1642
- * @private
1643
- * @param {Number} x x-coordinate of point
1644
- * @param {Number} y y-coordinate of point
1645
- * @param {Number} z z-coordinate of point
1646
- * @chainable
1647
- * @example
1648
- * <div>
1649
- * <code>
1650
- * function setup() {
1651
- * createCanvas(100, 100, WEBGL);
1652
- * }
1653
- *
1654
- * function draw() {
1655
- * background(50);
1656
- * stroke(255);
1657
- * strokeWeight(4);
1658
- * point(25, 0);
1659
- * strokeWeight(3);
1660
- * point(-25, 0);
1661
- * strokeWeight(2);
1662
- * point(0, 25);
1663
- * strokeWeight(1);
1664
- * point(0, -25);
1665
- * }
1666
- * </code>
1667
- * </div>
1668
- */
1669
- RendererGL.prototype.point = function(x, y, z = 0) {
1670
-
1671
- const _vertex = [];
1672
- _vertex.push(new Vector(x, y, z));
1673
- this._drawPoints(_vertex, this.buffers.point);
1674
-
1675
- return this;
1676
- };
1677
-
1678
- RendererGL.prototype.triangle = function(args) {
1679
- const x1 = args[0],
1680
- y1 = args[1];
1681
- const x2 = args[2],
1682
- y2 = args[3];
1683
- const x3 = args[4],
1684
- y3 = args[5];
1685
-
1686
- const gid = 'tri';
1687
- if (!this.geometryInHash(gid)) {
1688
- const _triangle = function() {
1689
- const vertices = [];
1690
- vertices.push(new Vector(0, 0, 0));
1691
- vertices.push(new Vector(1, 0, 0));
1692
- vertices.push(new Vector(0, 1, 0));
1693
- this.edges = [[0, 1], [1, 2], [2, 0]];
1694
- this.vertices = vertices;
1695
- this.faces = [[0, 1, 2]];
1696
- this.uvs = [0, 0, 1, 0, 1, 1];
1697
- };
1698
- const triGeom = new Geometry(1, 1, _triangle, this);
1699
- triGeom._edgesToVertices();
1700
- triGeom.computeNormals();
1701
- triGeom.gid = gid;
1702
- this.geometryBufferCache.ensureCached(triGeom);
1703
- }
1704
-
1705
- // only one triangle is cached, one point is at the origin, and the
1706
- // two adjacent sides are tne unit vectors along the X & Y axes.
1707
- //
1708
- // this matrix multiplication transforms those two unit vectors
1709
- // onto the required vector prior to rendering, and moves the
1710
- // origin appropriately.
1711
- const uModelMatrix = this.states.uModelMatrix.copy();
1712
- try {
1713
- // triangle orientation.
1714
- const orientation = Math.sign(x1*y2-x2*y1 + x2*y3-x3*y2 + x3*y1-x1*y3);
1715
- const mult = new Matrix([
1716
- x2 - x1, y2 - y1, 0, 0, // the resulting unit X-axis
1717
- x3 - x1, y3 - y1, 0, 0, // the resulting unit Y-axis
1718
- 0, 0, orientation, 0, // the resulting unit Z-axis (Reflect the specified order of vertices)
1719
- x1, y1, 0, 1 // the resulting origin
1720
- ]).mult(this.states.uModelMatrix);
1721
-
1722
- this.states.setValue('uModelMatrix', mult);
1723
-
1724
- this._drawGeometry(this.geometryBufferCache.getGeometryByID(gid));
1725
- } finally {
1726
- this.states.setValue('uModelMatrix', uModelMatrix);
1727
- }
1728
-
1729
- return this;
1730
- };
1731
-
1732
- RendererGL.prototype.ellipse = function(args) {
1733
- this.arc(
1734
- args[0],
1735
- args[1],
1736
- args[2],
1737
- args[3],
1738
- 0,
1739
- constants.TWO_PI,
1740
- constants.OPEN,
1741
- args[4]
1742
- );
1743
- };
1744
-
1745
- RendererGL.prototype.arc = function(...args) {
1746
- const x = args[0];
1747
- const y = args[1];
1748
- const width = args[2];
1749
- const height = args[3];
1750
- const start = args[4];
1751
- const stop = args[5];
1752
- const mode = args[6];
1753
- const detail = args[7] || 25;
1754
-
1755
- let shape;
1756
- let gid;
1757
-
1758
- // check if it is an ellipse or an arc
1759
- if (Math.abs(stop - start) >= constants.TWO_PI) {
1760
- shape = 'ellipse';
1761
- gid = `${shape}|${detail}|`;
1762
- } else {
1763
- shape = 'arc';
1764
- gid = `${shape}|${start}|${stop}|${mode}|${detail}|`;
1765
- }
1766
-
1767
- if (!this.geometryInHash(gid)) {
1768
- const _arc = function() {
1769
-
1770
- // if the start and stop angles are not the same, push vertices to the array
1771
- if (start.toFixed(10) !== stop.toFixed(10)) {
1772
- // if the mode specified is PIE or null, push the mid point of the arc in vertices
1773
- if (mode === constants.PIE || typeof mode === 'undefined') {
1774
- this.vertices.push(new Vector(0.5, 0.5, 0));
1775
- this.uvs.push([0.5, 0.5]);
1776
- }
1777
-
1778
- // vertices for the perimeter of the circle
1779
- for (let i = 0; i <= detail; i++) {
1780
- const u = i / detail;
1781
- const theta = (stop - start) * u + start;
1782
-
1783
- const _x = 0.5 + Math.cos(theta) / 2;
1784
- const _y = 0.5 + Math.sin(theta) / 2;
1785
-
1786
- this.vertices.push(new Vector(_x, _y, 0));
1787
- this.uvs.push([_x, _y]);
1788
-
1789
- if (i < detail - 1) {
1790
- this.faces.push([0, i + 1, i + 2]);
1791
- this.edges.push([i + 1, i + 2]);
1792
- }
1793
- }
1794
-
1795
- // check the mode specified in order to push vertices and faces, different for each mode
1796
- switch (mode) {
1797
- case constants.PIE:
1798
- this.faces.push([
1799
- 0,
1800
- this.vertices.length - 2,
1801
- this.vertices.length - 1
1802
- ]);
1803
- this.edges.push([0, 1]);
1804
- this.edges.push([
1805
- this.vertices.length - 2,
1806
- this.vertices.length - 1
1807
- ]);
1808
- this.edges.push([0, this.vertices.length - 1]);
1809
- break;
1810
-
1811
- case constants.CHORD:
1812
- this.edges.push([0, 1]);
1813
- this.edges.push([0, this.vertices.length - 1]);
1814
- break;
1815
-
1816
- case constants.OPEN:
1817
- this.edges.push([0, 1]);
1818
- break;
1819
-
1820
- default:
1821
- this.faces.push([
1822
- 0,
1823
- this.vertices.length - 2,
1824
- this.vertices.length - 1
1825
- ]);
1826
- this.edges.push([
1827
- this.vertices.length - 2,
1828
- this.vertices.length - 1
1829
- ]);
1830
- }
1831
- }
1832
- };
1833
-
1834
- const arcGeom = new Geometry(detail, 1, _arc, this);
1835
- arcGeom.computeNormals();
1836
-
1837
- if (detail <= 50) {
1838
- arcGeom._edgesToVertices(arcGeom);
1839
- } else if (this.states.strokeColor) {
1840
- console.log(
1841
- `Cannot apply a stroke to an ${shape} with more than 50 detail`
1842
- );
1843
- }
1844
-
1845
- arcGeom.gid = gid;
1846
- this.geometryBufferCache.ensureCached(arcGeom);
1847
- }
1848
-
1849
- const uModelMatrix = this.states.uModelMatrix;
1850
- this.states.setValue('uModelMatrix', this.states.uModelMatrix.clone());
1851
-
1852
- try {
1853
- this.states.uModelMatrix.translate([x, y, 0]);
1854
- this.states.uModelMatrix.scale(width, height, 1);
1855
-
1856
- this._drawGeometry(this.geometryBufferCache.getGeometryByID(gid));
1857
- } finally {
1858
- this.states.setValue('uModelMatrix', uModelMatrix);
1859
- }
1860
-
1861
- return this;
1862
- };
1863
-
1864
- RendererGL.prototype.rect = function(args) {
1865
- const x = args[0];
1866
- const y = args[1];
1867
- const width = args[2];
1868
- const height = args[3];
1869
-
1870
- if (typeof args[4] === 'undefined') {
1871
- // Use the retained mode for drawing rectangle,
1872
- // if args for rounding rectangle is not provided by user.
1873
- const perPixelLighting = this._pInst._glAttributes.perPixelLighting;
1874
- const detailX = args[4] || (perPixelLighting ? 1 : 24);
1875
- const detailY = args[5] || (perPixelLighting ? 1 : 16);
1876
- const gid = `rect|${detailX}|${detailY}`;
1877
- if (!this.geometryInHash(gid)) {
1878
- const _rect = function() {
1879
- for (let i = 0; i <= this.detailY; i++) {
1880
- const v = i / this.detailY;
1881
- for (let j = 0; j <= this.detailX; j++) {
1882
- const u = j / this.detailX;
1883
- const p = new Vector(u, v, 0);
1884
- this.vertices.push(p);
1885
- this.uvs.push(u, v);
1886
- }
1887
- }
1888
- // using stroke indices to avoid stroke over face(s) of rectangle
1889
- if (detailX > 0 && detailY > 0) {
1890
- this.edges = [
1891
- [0, detailX],
1892
- [detailX, (detailX + 1) * (detailY + 1) - 1],
1893
- [(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
1894
- [(detailX + 1) * detailY, 0]
1895
- ];
1896
- }
1897
- };
1898
- const rectGeom = new Geometry(detailX, detailY, _rect, this);
1899
- rectGeom
1900
- .computeFaces()
1901
- .computeNormals()
1902
- ._edgesToVertices();
1903
- rectGeom.gid = gid;
1904
- this.geometryBufferCache.ensureCached(rectGeom);
1905
- }
1906
-
1907
- // only a single rectangle (of a given detail) is cached: a square with
1908
- // opposite corners at (0,0) & (1,1).
1909
- //
1910
- // before rendering, this square is scaled & moved to the required location.
1911
- const uModelMatrix = this.states.uModelMatrix;
1912
- this.states.setValue('uModelMatrix', this.states.uModelMatrix.copy());
1913
- try {
1914
- this.states.uModelMatrix.translate([x, y, 0]);
1915
- this.states.uModelMatrix.scale(width, height, 1);
1916
-
1917
- this._drawGeometry(this.geometryBufferCache.getGeometryByID(gid));
1918
- } finally {
1919
- this.states.setValue('uModelMatrix', uModelMatrix);
1920
- }
1921
- } else {
1922
- // Use Immediate mode to round the rectangle corner,
1923
- // if args for rounding corners is provided by user
1924
- let tl = args[4];
1925
- let tr = typeof args[5] === 'undefined' ? tl : args[5];
1926
- let br = typeof args[6] === 'undefined' ? tr : args[6];
1927
- let bl = typeof args[7] === 'undefined' ? br : args[7];
1928
-
1929
- let a = x;
1930
- let b = y;
1931
- let c = width;
1932
- let d = height;
1933
-
1934
- c += a;
1935
- d += b;
1936
-
1937
- if (a > c) {
1938
- const temp = a;
1939
- a = c;
1940
- c = temp;
1941
- }
1942
-
1943
- if (b > d) {
1944
- const temp = b;
1945
- b = d;
1946
- d = temp;
1947
- }
1948
-
1949
- const maxRounding = Math.min((c - a) / 2, (d - b) / 2);
1950
- if (tl > maxRounding) tl = maxRounding;
1951
- if (tr > maxRounding) tr = maxRounding;
1952
- if (br > maxRounding) br = maxRounding;
1953
- if (bl > maxRounding) bl = maxRounding;
1954
-
1955
- let x1 = a;
1956
- let y1 = b;
1957
- let x2 = c;
1958
- let y2 = d;
1959
-
1960
- const prevMode = this.states.textureMode;
1961
- this.states.setValue('textureMode', constants.NORMAL);
1962
- const prevOrder = this.bezierOrder();
1963
- this.bezierOrder(2);
1964
- this.beginShape();
1965
- const addUVs = (x, y) => [x, y, (x - x1)/width, (y - y1)/height];
1966
- if (tr !== 0) {
1967
- this.vertex(...addUVs(x2 - tr, y1));
1968
- this.bezierVertex(...addUVs(x2, y1))
1969
- this.bezierVertex(...addUVs(x2, y1 + tr));
1970
- } else {
1971
- this.vertex(...addUVs(x2, y1));
1972
- }
1973
- if (br !== 0) {
1974
- this.vertex(...addUVs(x2, y2 - br));
1975
- this.bezierVertex(...addUVs(x2, y2));
1976
- this.bezierVertex(...addUVs(x2 - br, y2))
1977
- } else {
1978
- this.vertex(...addUVs(x2, y2));
1979
- }
1980
- if (bl !== 0) {
1981
- this.vertex(...addUVs(x1 + bl, y2));
1982
- this.bezierVertex(...addUVs(x1, y2));
1983
- this.bezierVertex(...addUVs(x1, y2 - bl));
1984
- } else {
1985
- this.vertex(...addUVs(x1, y2));
1986
- }
1987
- if (tl !== 0) {
1988
- this.vertex(...addUVs(x1, y1 + tl));
1989
- this.bezierVertex(...addUVs(x1, y1));
1990
- this.bezierVertex(...addUVs(x1 + tl, y1));
1991
- } else {
1992
- this.vertex(...addUVs(x1, y1));
1993
- }
1994
-
1995
- this.endShape(constants.CLOSE);
1996
- this.states.setValue('textureMode', prevMode);
1997
- this.bezierOrder(prevOrder);
1998
- }
1999
- return this;
2000
- };
2001
-
2002
- /* eslint-disable max-len */
2003
- RendererGL.prototype.quad = function(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, detailX=2, detailY=2) {
2004
- /* eslint-enable max-len */
2005
-
2006
- const gid =
2007
- `quad|${x1}|${y1}|${z1}|${x2}|${y2}|${z2}|${x3}|${y3}|${z3}|${x4}|${y4}|${z4}|${detailX}|${detailY}`;
2008
-
2009
- if (!this.geometryInHash(gid)) {
2010
- const quadGeom = new Geometry(detailX, detailY, function() {
2011
- //algorithm adapted from c++ to js
2012
- //https://stackoverflow.com/questions/16989181/whats-the-correct-way-to-draw-a-distorted-plane-in-opengl/16993202#16993202
2013
- let xRes = 1.0 / (this.detailX - 1);
2014
- let yRes = 1.0 / (this.detailY - 1);
2015
- for (let y = 0; y < this.detailY; y++) {
2016
- for (let x = 0; x < this.detailX; x++) {
2017
- let pctx = x * xRes;
2018
- let pcty = y * yRes;
2019
-
2020
- let linePt0x = (1 - pcty) * x1 + pcty * x4;
2021
- let linePt0y = (1 - pcty) * y1 + pcty * y4;
2022
- let linePt0z = (1 - pcty) * z1 + pcty * z4;
2023
- let linePt1x = (1 - pcty) * x2 + pcty * x3;
2024
- let linePt1y = (1 - pcty) * y2 + pcty * y3;
2025
- let linePt1z = (1 - pcty) * z2 + pcty * z3;
2026
-
2027
- let ptx = (1 - pctx) * linePt0x + pctx * linePt1x;
2028
- let pty = (1 - pctx) * linePt0y + pctx * linePt1y;
2029
- let ptz = (1 - pctx) * linePt0z + pctx * linePt1z;
2030
-
2031
- this.vertices.push(new Vector(ptx, pty, ptz));
2032
- this.uvs.push([pctx, pcty]);
2033
- }
2034
- }
2035
- }, this);
2036
-
2037
- quadGeom.faces = [];
2038
- for(let y = 0; y < detailY-1; y++){
2039
- for(let x = 0; x < detailX-1; x++){
2040
- let pt0 = x + y * detailX;
2041
- let pt1 = (x + 1) + y * detailX;
2042
- let pt2 = (x + 1) + (y + 1) * detailX;
2043
- let pt3 = x + (y + 1) * detailX;
2044
- quadGeom.faces.push([pt0, pt1, pt2]);
2045
- quadGeom.faces.push([pt0, pt2, pt3]);
2046
- }
2047
- }
2048
- quadGeom.computeNormals();
2049
- quadGeom.edges.length = 0;
2050
- const vertexOrder = [0, 2, 3, 1];
2051
- for (let i = 0; i < vertexOrder.length; i++) {
2052
- const startVertex = vertexOrder[i];
2053
- const endVertex = vertexOrder[(i + 1) % vertexOrder.length];
2054
- quadGeom.edges.push([startVertex, endVertex]);
2055
- }
2056
- quadGeom._edgesToVertices();
2057
- quadGeom.gid = gid;
2058
- this.geometryBufferCache.ensureCached(quadGeom);
2059
- }
2060
- this._drawGeometry(this.geometryBufferCache.getGeometryByID(gid));
2061
- return this;
2062
- };
2063
-
2064
- //this implementation of bezier curve
2065
- //is based on Bernstein polynomial
2066
- // pretier-ignore
2067
- RendererGL.prototype.bezier = function(
2068
- x1,
2069
- y1,
2070
- z1, // x2
2071
- x2, // y2
2072
- y2, // x3
2073
- z2, // y3
2074
- x3, // x4
2075
- y3, // y4
2076
- z3,
2077
- x4,
2078
- y4,
2079
- z4
2080
- ) {
2081
- if (arguments.length === 8) {
2082
- y4 = y3;
2083
- x4 = x3;
2084
- y3 = z2;
2085
- x3 = y2;
2086
- y2 = x2;
2087
- x2 = z1;
2088
- z1 = z2 = z3 = z4 = 0;
2089
- }
2090
- // TODO: handle quadratic?
2091
- const prevOrder = this.bezierOrder();
2092
- this.bezierOrder(3);
2093
- this.beginShape();
2094
- this.vertex(x1, y1, z1);
2095
- this.bezierVertex(x2, y2, z2);
2096
- this.bezierVertex(x3, y3, z3);
2097
- this.bezierVertex(x4, y4, z4);
2098
- this.endShape();
2099
- };
2100
-
2101
- // pretier-ignore
2102
- RendererGL.prototype.curve = function(
2103
- x1,
2104
- y1,
2105
- z1, // x2
2106
- x2, // y2
2107
- y2, // x3
2108
- z2, // y3
2109
- x3, // x4
2110
- y3, // y4
2111
- z3,
2112
- x4,
2113
- y4,
2114
- z4
2115
- ) {
2116
- if (arguments.length === 8) {
2117
- x4 = x3;
2118
- y4 = y3;
2119
- x3 = y2;
2120
- y3 = x2;
2121
- x2 = z1;
2122
- y2 = x2;
2123
- z1 = z2 = z3 = z4 = 0;
2124
- }
2125
- this.beginShape();
2126
- this.splineVertex(x1, y1, z1);
2127
- this.splineVertex(x2, y2, z2);
2128
- this.splineVertex(x3, y3, z3);
2129
- this.splineVertex(x4, y4, z4);
2130
- this.endShape();
2131
- };
2132
-
2133
- /**
2134
- * Draw a line given two points
2135
- * @private
2136
- * @param {Number} x0 x-coordinate of first vertex
2137
- * @param {Number} y0 y-coordinate of first vertex
2138
- * @param {Number} z0 z-coordinate of first vertex
2139
- * @param {Number} x1 x-coordinate of second vertex
2140
- * @param {Number} y1 y-coordinate of second vertex
2141
- * @param {Number} z1 z-coordinate of second vertex
2142
- * @chainable
2143
- * @example
2144
- * <div>
2145
- * <code>
2146
- * //draw a line
2147
- * function setup() {
2148
- * createCanvas(100, 100, WEBGL);
2149
- * }
2150
- *
2151
- * function draw() {
2152
- * background(200);
2153
- * rotateX(frameCount * 0.01);
2154
- * rotateY(frameCount * 0.01);
2155
- * // Use fill instead of stroke to change the color of shape.
2156
- * fill(255, 0, 0);
2157
- * line(10, 10, 0, 60, 60, 20);
2158
- * }
2159
- * </code>
2160
- * </div>
2161
- */
2162
- RendererGL.prototype.line = function(...args) {
2163
- if (args.length === 6) {
2164
- // TODO shapes refactor
2165
- this.beginShape(constants.LINES);
2166
- this.vertex(args[0], args[1], args[2]);
2167
- this.vertex(args[3], args[4], args[5]);
2168
- this.endShape();
2169
- } else if (args.length === 4) {
2170
- this.beginShape(constants.LINES);
2171
- this.vertex(args[0], args[1], 0);
2172
- this.vertex(args[2], args[3], 0);
2173
- this.endShape();
2174
- }
2175
- return this;
2176
- };
2177
-
2178
- RendererGL.prototype.image = function(
2179
- img,
2180
- sx,
2181
- sy,
2182
- sWidth,
2183
- sHeight,
2184
- dx,
2185
- dy,
2186
- dWidth,
2187
- dHeight
2188
- ) {
2189
- // console.log(arguments);
2190
- if (this._isErasing) {
2191
- this.blendMode(this._cachedBlendMode);
2192
- }
2193
-
2194
- this.push();
2195
- this.noLights();
2196
- this.states.setValue('strokeColor', null);
2197
-
2198
- this.texture(img);
2199
- this.states.setValue('textureMode', constants.NORMAL);
2200
-
2201
- let u0 = 0;
2202
- if (sx <= img.width) {
2203
- u0 = sx / img.width;
2204
- }
2205
-
2206
- let u1 = 1;
2207
- if (sx + sWidth <= img.width) {
2208
- u1 = (sx + sWidth) / img.width;
2209
- }
2210
-
2211
- let v0 = 0;
2212
- if (sy <= img.height) {
2213
- v0 = sy / img.height;
2214
- }
2215
-
2216
- let v1 = 1;
2217
- if (sy + sHeight <= img.height) {
2218
- v1 = (sy + sHeight) / img.height;
2219
- }
2220
-
2221
- this._drawingImage = true;
2222
- this.beginShape();
2223
- this.vertex(dx, dy, 0, u0, v0);
2224
- this.vertex(dx + dWidth, dy, 0, u1, v0);
2225
- this.vertex(dx + dWidth, dy + dHeight, 0, u1, v1);
2226
- this.vertex(dx, dy + dHeight, 0, u0, v1);
2227
- this.endShape(constants.CLOSE);
2228
- this._drawingImage = false;
2229
-
2230
- this.pop();
2231
-
2232
- if (this._isErasing) {
2233
- this.blendMode(constants.REMOVE);
2234
- }
2235
- };
2236
-
2237
- ///////////////////////
2238
- /// 3D primitives ///
2239
- ///////////////////////
2240
- /**
2241
- * @private
2242
- * Helper function for creating both cones and cylinders
2243
- * Will only generate well-defined geometry when bottomRadius, height > 0
2244
- * and topRadius >= 0
2245
- * If topRadius == 0, topCap should be false
2246
- */
2247
- const _truncatedCone = function(
2248
- bottomRadius,
2249
- topRadius,
2250
- height,
2251
- detailX,
2252
- detailY,
2253
- bottomCap,
2254
- topCap
2255
- ) {
2256
- bottomRadius = bottomRadius <= 0 ? 1 : bottomRadius;
2257
- topRadius = topRadius < 0 ? 0 : topRadius;
2258
- height = height <= 0 ? bottomRadius : height;
2259
- detailX = detailX < 3 ? 3 : detailX;
2260
- detailY = detailY < 1 ? 1 : detailY;
2261
- bottomCap = bottomCap === undefined ? true : bottomCap;
2262
- topCap = topCap === undefined ? topRadius !== 0 : topCap;
2263
- const start = bottomCap ? -2 : 0;
2264
- const end = detailY + (topCap ? 2 : 0);
2265
- //ensure constant slant for interior vertex normals
2266
- const slant = Math.atan2(bottomRadius - topRadius, height);
2267
- const sinSlant = Math.sin(slant);
2268
- const cosSlant = Math.cos(slant);
2269
- let yy, ii, jj;
2270
- for (yy = start; yy <= end; ++yy) {
2271
- let v = yy / detailY;
2272
- let y = height * v;
2273
- let ringRadius;
2274
- if (yy < 0) {
2275
- //for the bottomCap edge
2276
- y = 0;
2277
- v = 0;
2278
- ringRadius = bottomRadius;
2279
- } else if (yy > detailY) {
2280
- //for the topCap edge
2281
- y = height;
2282
- v = 1;
2283
- ringRadius = topRadius;
2284
- } else {
2285
- //for the middle
2286
- ringRadius = bottomRadius + (topRadius - bottomRadius) * v;
2287
- }
2288
- if (yy === -2 || yy === detailY + 2) {
2289
- //center of bottom or top caps
2290
- ringRadius = 0;
2291
- }
2292
-
2293
- y -= height / 2; //shift coordiate origin to the center of object
2294
- for (ii = 0; ii < detailX; ++ii) {
2295
- const u = ii / (detailX - 1);
2296
- const ur = 2 * Math.PI * u;
2297
- const sur = Math.sin(ur);
2298
- const cur = Math.cos(ur);
2299
-
2300
- //VERTICES
2301
- this.vertices.push(new Vector(sur * ringRadius, y, cur * ringRadius));
2302
-
2303
- //VERTEX NORMALS
2304
- let vertexNormal;
2305
- if (yy < 0) {
2306
- vertexNormal = new Vector(0, -1, 0);
2307
- } else if (yy > detailY && topRadius) {
2308
- vertexNormal = new Vector(0, 1, 0);
2309
- } else {
2310
- vertexNormal = new Vector(sur * cosSlant, sinSlant, cur * cosSlant);
2311
- }
2312
- this.vertexNormals.push(vertexNormal);
2313
- //UVs
2314
- this.uvs.push(u, v);
2315
- }
2316
- }
2317
-
2318
- let startIndex = 0;
2319
- if (bottomCap) {
2320
- for (jj = 0; jj < detailX; ++jj) {
2321
- const nextjj = (jj + 1) % detailX;
2322
- this.faces.push([
2323
- startIndex + jj,
2324
- startIndex + detailX + nextjj,
2325
- startIndex + detailX + jj
2326
- ]);
2327
- }
2328
- startIndex += detailX * 2;
2329
- }
2330
- for (yy = 0; yy < detailY; ++yy) {
2331
- for (ii = 0; ii < detailX; ++ii) {
2332
- const nextii = (ii + 1) % detailX;
2333
- this.faces.push([
2334
- startIndex + ii,
2335
- startIndex + nextii,
2336
- startIndex + detailX + nextii
2337
- ]);
2338
- this.faces.push([
2339
- startIndex + ii,
2340
- startIndex + detailX + nextii,
2341
- startIndex + detailX + ii
2342
- ]);
2343
- }
2344
- startIndex += detailX;
2345
- }
2346
- if (topCap) {
2347
- startIndex += detailX;
2348
- for (ii = 0; ii < detailX; ++ii) {
2349
- this.faces.push([
2350
- startIndex + ii,
2351
- startIndex + (ii + 1) % detailX,
2352
- startIndex + detailX
2353
- ]);
2354
- }
2355
- }
2356
- };
2357
-
2358
- RendererGL.prototype.plane = function(
2359
- width = 50,
2360
- height = width,
2361
- detailX = 1,
2362
- detailY = 1
2363
- ) {
2364
- const gid = `plane|${detailX}|${detailY}`;
2365
-
2366
- if (!this.geometryInHash(gid)) {
2367
- const _plane = function() {
2368
- let u, v, p;
2369
- for (let i = 0; i <= this.detailY; i++) {
2370
- v = i / this.detailY;
2371
- for (let j = 0; j <= this.detailX; j++) {
2372
- u = j / this.detailX;
2373
- p = new Vector(u - 0.5, v - 0.5, 0);
2374
- this.vertices.push(p);
2375
- this.uvs.push(u, v);
2376
- }
2377
- }
2378
- };
2379
- const planeGeom = new Geometry(detailX, detailY, _plane, this);
2380
- planeGeom.computeFaces().computeNormals();
2381
- if (detailX <= 1 && detailY <= 1) {
2382
- planeGeom._makeTriangleEdges()._edgesToVertices();
2383
- } else if (this.states.strokeColor) {
2384
- console.log(
2385
- 'Cannot draw stroke on plane objects with more' +
2386
- ' than 1 detailX or 1 detailY'
2387
- );
2388
- }
2389
- planeGeom.gid = gid;
2390
- this.geometryBufferCache.ensureCached(planeGeom);
2391
- }
2392
-
2393
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), width, height, 1);
2394
- }
2395
-
2396
- RendererGL.prototype.box = function(
2397
- width = 50,
2398
- height = width,
2399
- depth = height,
2400
- detailX,
2401
- detailY
2402
- ){
2403
- const perPixelLighting =
2404
- this.attributes && this.attributes.perPixelLighting;
2405
- if (typeof detailX === 'undefined') {
2406
- detailX = perPixelLighting ? 1 : 4;
2407
- }
2408
- if (typeof detailY === 'undefined') {
2409
- detailY = perPixelLighting ? 1 : 4;
2410
- }
2411
-
2412
- const gid = `box|${detailX}|${detailY}`;
2413
- if (!this.geometryInHash(gid)) {
2414
- const _box = function() {
2415
- const cubeIndices = [
2416
- [0, 4, 2, 6], // -1, 0, 0],// -x
2417
- [1, 3, 5, 7], // +1, 0, 0],// +x
2418
- [0, 1, 4, 5], // 0, -1, 0],// -y
2419
- [2, 6, 3, 7], // 0, +1, 0],// +y
2420
- [0, 2, 1, 3], // 0, 0, -1],// -z
2421
- [4, 5, 6, 7] // 0, 0, +1] // +z
2422
- ];
2423
- //using custom edges
2424
- //to avoid diagonal stroke lines across face of box
2425
- this.edges = [
2426
- [0, 1],
2427
- [1, 3],
2428
- [3, 2],
2429
- [6, 7],
2430
- [8, 9],
2431
- [9, 11],
2432
- [14, 15],
2433
- [16, 17],
2434
- [17, 19],
2435
- [18, 19],
2436
- [20, 21],
2437
- [22, 23]
2438
- ];
2439
-
2440
- cubeIndices.forEach((cubeIndex, i) => {
2441
- const v = i * 4;
2442
- for (let j = 0; j < 4; j++) {
2443
- const d = cubeIndex[j];
2444
- //inspired by lightgl:
2445
- //https://github.com/evanw/lightgl.js
2446
- //octants:https://en.wikipedia.org/wiki/Octant_(solid_geometry)
2447
- const octant = new Vector(
2448
- ((d & 1) * 2 - 1) / 2,
2449
- ((d & 2) - 1) / 2,
2450
- ((d & 4) / 2 - 1) / 2
2451
- );
2452
- this.vertices.push(octant);
2453
- this.uvs.push(j & 1, (j & 2) / 2);
2454
- }
2455
- this.faces.push([v, v + 1, v + 2]);
2456
- this.faces.push([v + 2, v + 1, v + 3]);
2457
- });
2458
- };
2459
- const boxGeom = new Geometry(detailX, detailY, _box, this);
2460
- boxGeom.computeNormals();
2461
- if (detailX <= 4 && detailY <= 4) {
2462
- boxGeom._edgesToVertices();
2463
- } else if (this.states.strokeColor) {
2464
- console.log(
2465
- 'Cannot draw stroke on box objects with more' +
2466
- ' than 4 detailX or 4 detailY'
2467
- );
2468
- }
2469
- //initialize our geometry buffer with
2470
- //the key val pair:
2471
- //geometry Id, Geom object
2472
- boxGeom.gid = gid;
2473
- this.geometryBufferCache.ensureCached(boxGeom);
2474
- }
2475
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), width, height, depth);
2476
- }
2477
-
2478
- RendererGL.prototype.sphere = function(
2479
- radius = 50,
2480
- detailX = 24,
2481
- detailY = 16
2482
- ) {
2483
- this.ellipsoid(radius, radius, radius, detailX, detailY);
2484
- }
2485
-
2486
- RendererGL.prototype.ellipsoid = function(
2487
- radiusX = 50,
2488
- radiusY = radiusX,
2489
- radiusZ = radiusX,
2490
- detailX = 24,
2491
- detailY = 16
2492
- ) {
2493
- const gid = `ellipsoid|${detailX}|${detailY}`;
2494
-
2495
- if (!this.geometryInHash(gid)) {
2496
- const _ellipsoid = function() {
2497
- for (let i = 0; i <= this.detailY; i++) {
2498
- const v = i / this.detailY;
2499
- const phi = Math.PI * v - Math.PI / 2;
2500
- const cosPhi = Math.cos(phi);
2501
- const sinPhi = Math.sin(phi);
2502
-
2503
- for (let j = 0; j <= this.detailX; j++) {
2504
- const u = j / this.detailX;
2505
- const theta = 2 * Math.PI * u;
2506
- const cosTheta = Math.cos(theta);
2507
- const sinTheta = Math.sin(theta);
2508
- const p = new p5.Vector(cosPhi * sinTheta, sinPhi, cosPhi * cosTheta);
2509
- this.vertices.push(p);
2510
- this.vertexNormals.push(p);
2511
- this.uvs.push(u, v);
2512
- }
2513
- }
2514
- };
2515
- const ellipsoidGeom = new Geometry(detailX, detailY, _ellipsoid, this);
2516
- ellipsoidGeom.computeFaces();
2517
- if (detailX <= 24 && detailY <= 24) {
2518
- ellipsoidGeom._makeTriangleEdges()._edgesToVertices();
2519
- } else if (this.states.strokeColor) {
2520
- console.log(
2521
- 'Cannot draw stroke on ellipsoids with more' +
2522
- ' than 24 detailX or 24 detailY'
2523
- );
2524
- }
2525
- ellipsoidGeom.gid = gid;
2526
- this.geometryBufferCache.ensureCached(ellipsoidGeom);
2527
- }
2528
-
2529
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), radiusX, radiusY, radiusZ);
2530
- }
2531
-
2532
- RendererGL.prototype.cylinder = function(
2533
- radius = 50,
2534
- height = radius,
2535
- detailX = 24,
2536
- detailY = 1,
2537
- bottomCap = true,
2538
- topCap = true
2539
- ) {
2540
- const gid = `cylinder|${detailX}|${detailY}|${bottomCap}|${topCap}`;
2541
- if (!this.geometryInHash(gid)) {
2542
- const cylinderGeom = new p5.Geometry(detailX, detailY, function() {
2543
- _truncatedCone.call(
2544
- this,
2545
- 1,
2546
- 1,
2547
- 1,
2548
- detailX,
2549
- detailY,
2550
- bottomCap,
2551
- topCap
2552
- );
2553
- }, this);
2554
- // normals are computed in call to _truncatedCone
2555
- if (detailX <= 24 && detailY <= 16) {
2556
- cylinderGeom._makeTriangleEdges()._edgesToVertices();
2557
- } else if (this.states.strokeColor) {
2558
- console.log(
2559
- 'Cannot draw stroke on cylinder objects with more' +
2560
- ' than 24 detailX or 16 detailY'
2561
- );
2562
- }
2563
- cylinderGeom.gid = gid;
2564
- this.geometryBufferCache.ensureCached(cylinderGeom);
2565
- }
2566
-
2567
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), radius, height, radius);
2568
- }
2569
-
2570
- RendererGL.prototype.cone = function(
2571
- radius = 50,
2572
- height = radius,
2573
- detailX = 24,
2574
- detailY = 1,
2575
- cap = true
2576
- ) {
2577
- const gid = `cone|${detailX}|${detailY}|${cap}`;
2578
- if (!this.geometryInHash(gid)) {
2579
- const coneGeom = new Geometry(detailX, detailY, function() {
2580
- _truncatedCone.call(
2581
- this,
2582
- 1,
2583
- 0,
2584
- 1,
2585
- detailX,
2586
- detailY,
2587
- cap,
2588
- false
2589
- );
2590
- }, this);
2591
- if (detailX <= 24 && detailY <= 16) {
2592
- coneGeom._makeTriangleEdges()._edgesToVertices();
2593
- } else if (this.states.strokeColor) {
2594
- console.log(
2595
- 'Cannot draw stroke on cone objects with more' +
2596
- ' than 24 detailX or 16 detailY'
2597
- );
2598
- }
2599
- coneGeom.gid = gid;
2600
- this.geometryBufferCache.ensureCached(coneGeom);
2601
- }
2602
-
2603
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), radius, height, radius);
2604
- }
2605
-
2606
- RendererGL.prototype.torus = function(
2607
- radius = 50,
2608
- tubeRadius = 10,
2609
- detailX = 24,
2610
- detailY = 16
2611
- ) {
2612
- if (radius === 0) {
2613
- return; // nothing to draw
2614
- }
2615
-
2616
- if (tubeRadius === 0) {
2617
- return; // nothing to draw
2618
- }
2619
-
2620
- const tubeRatio = (tubeRadius / radius).toPrecision(4);
2621
- const gid = `torus|${tubeRatio}|${detailX}|${detailY}`;
2622
-
2623
- if (!this.geometryInHash(gid)) {
2624
- const _torus = function() {
2625
- for (let i = 0; i <= this.detailY; i++) {
2626
- const v = i / this.detailY;
2627
- const phi = 2 * Math.PI * v;
2628
- const cosPhi = Math.cos(phi);
2629
- const sinPhi = Math.sin(phi);
2630
- const r = 1 + tubeRatio * cosPhi;
2631
-
2632
- for (let j = 0; j <= this.detailX; j++) {
2633
- const u = j / this.detailX;
2634
- const theta = 2 * Math.PI * u;
2635
- const cosTheta = Math.cos(theta);
2636
- const sinTheta = Math.sin(theta);
2637
-
2638
- const p = new Vector(
2639
- r * cosTheta,
2640
- r * sinTheta,
2641
- tubeRatio * sinPhi
2642
- );
2643
-
2644
- const n = new Vector(cosPhi * cosTheta, cosPhi * sinTheta, sinPhi);
2645
-
2646
- this.vertices.push(p);
2647
- this.vertexNormals.push(n);
2648
- this.uvs.push(u, v);
2649
- }
2650
- }
2651
- };
2652
- const torusGeom = new Geometry(detailX, detailY, _torus, this);
2653
- torusGeom.computeFaces();
2654
- if (detailX <= 24 && detailY <= 16) {
2655
- torusGeom._makeTriangleEdges()._edgesToVertices();
2656
- } else if (this.states.strokeColor) {
2657
- console.log(
2658
- 'Cannot draw strokes on torus object with more' +
2659
- ' than 24 detailX or 16 detailY'
2660
- );
2661
- }
2662
- torusGeom.gid = gid;
2663
- this.geometryBufferCache.ensureCached(torusGeom);
2664
- }
2665
- this._drawGeometryScaled(this.geometryBufferCache.getGeometryByID(gid), radius, radius, radius);
2666
- }
2667
-
2668
- /**
2669
- * Sets the number of segments used to draw spline curves in WebGL mode.
2670
- *
2671
- * In WebGL mode, smooth shapes are drawn using many flat segments. Adding
2672
- * more flat segments makes shapes appear smoother.
2673
- *
2674
- * The parameter, `detail`, is the density of segments to use while drawing a
2675
- * spline curve.
2676
- *
2677
- * Note: `curveDetail()` has no effect in 2D mode.
2678
- *
2679
- * @method curveDetail
2680
- * @param {Number} resolution number of segments to use. Default is 1/4
2681
- * @chainable
2682
- *
2683
- * @example
2684
- *
2685
- * <div>
2686
- * <code>
2687
- * function setup() {
2688
- * createCanvas(100, 100, WEBGL);
2689
- *
2690
- * background(200);
2691
- *
2692
- * // Set the curveDetail() to 0.5
2693
- * curveDetail(0.5);
2694
- *
2695
- * // Do not show all the vertices
2696
- * splineProperty('ends', EXCLUDE)
2697
- *
2698
- * // Draw a black spline curve.
2699
- * noFill();
2700
- * strokeWeight(1);
2701
- * stroke(0);
2702
- * spline(-45, -24, 0, 23, -26, 0, 23, 11, 0, -35, 15, 0);
2703
- *
2704
- * // Draw red spline curves from the anchor points to the control points.
2705
- * spline(255, 0, 0);
2706
- * spline(-45, -24, 0, -45, -24, 0, 23, -26, 0, 23, 11, 0);
2707
- * spline(23, -26, 0, 23, 11, 0, -35, 15, 0, -35, 15, 0);
2708
- *
2709
- * // Draw the anchor points in black.
2710
- * strokeWeight(5);
2711
- * stroke(0);
2712
- * point(23, -26);
2713
- * point(23, 11);
2714
- *
2715
- * // Draw the control points in red.
2716
- * stroke(255, 0, 0);
2717
- * point(-45, -24);
2718
- * point(-35, 15);
2719
- *
2720
- * describe(
2721
- * 'A gray square with a jagged curve drawn in three segments. The curve is a sideways U shape with red segments on top and bottom, and a black segment on the right. The endpoints of all the segments are marked with dots.'
2722
- * );
2723
- * }
2724
- * </code>
2725
- * </div>
2726
- */
2727
- fn.curveDetail = function(d) {
2728
- if (!(this._renderer instanceof RendererGL)) {
2729
- throw new Error(
2730
- 'curveDetail() only works in WebGL mode. Did you mean to call createCanvas(width, height, WEBGL)?'
2731
- );
2732
- }
2733
- return this._renderer.curveDetail(d);
2734
- };
2735
- }
2736
-
2737
- export default primitives3D;
2738
-
2739
- if(typeof p5 !== 'undefined'){
2740
- primitives3D(p5, p5.prototype);
2741
- }