1.3.49
 
Loading...
Searching...
No Matches
sorghum.cpp
1#include "CanopyGenerator.h"
2
3using namespace std;
4using namespace helios;
5
6
7// SORGHUM PLANT
9 // STAGE 1
10 if (params.sorghum_stage == 1) {
11
12 std::vector<vec3> node_stem;
13 vector<RGBcolor> Color_stem;
14
15 std::vector<float> radius_stem;
16
17 // map the route for the stem
18 float stem_sects = params.s1_stem_length * 0.1; // split the stem length into 10 parts
19
20 for (float n = 0; n < params.s1_stem_length + stem_sects; n = n + stem_sects) {
21 float y = 0;
22 float x = 0;
23 float z = n;
24
25 node_stem.push_back(make_vec3(x, y, z) + origin);
26 radius_stem.push_back(params.s1_stem_radius);
27 Color_stem.push_back(make_RGBcolor(0.44, 0.58, 0.19));
28 }
29
30 std::vector<std::vector<uint>> s1_UUID_stem_plant;
31 s1_UUID_stem_plant.resize(1);
32 std::vector<uint> UUID_stem = context->addTube(params.s1_stem_subdivisions, node_stem, radius_stem, Color_stem);
33 std::vector<uint> UUID_stem_top = context->addDisk(params.s1_stem_subdivisions, make_vec3(0, 0, 0), make_vec2(params.s1_stem_radius, params.s1_stem_radius), make_SphericalCoord(0, 0, 0), RGBcolor(0.44, 0.58, 0.19));
34
35 vec3 base_top = interpolateTube(node_stem, 1);
36 context->translatePrimitive(UUID_stem_top, base_top);
37
38 s1_UUID_stem_plant.push_back(context->copyPrimitive(UUID_stem));
39 s1_UUID_stem_plant.push_back(context->copyPrimitive(UUID_stem_top));
40 context->deletePrimitive(UUID_stem);
41 context->deletePrimitive(UUID_stem_top);
42
43
44 float angle = ((context->randu(0, 90) * PI_F) / float(180));
45 for (float i = 1; i < 4; i++) {
46 float leaf_length, leaf_width, rotation_value1, leaf_bend, rotation_value2, frac, leaf_curve, x_adj;
47
48 if (i == 1) {
49 leaf_length = params.s1_leaf_size1.x;
50 leaf_width = params.s1_leaf_size1.y;
51 rotation_value1 = 0; // rotation in the y axis
52 leaf_bend = leaf_length * 0.2;
53 rotation_value2 = params.s1_leaf1_angle; // leaf rotation on the z axis
54 frac = 0.9;
55 leaf_curve = leaf_width * 0.25;
56 x_adj = 0;
57
58 } else if (i == 2) {
59 leaf_length = params.s1_leaf_size2.x;
60 leaf_width = params.s1_leaf_size2.y;
61 rotation_value1 = PI_F;
62 leaf_bend = leaf_length * 0.2;
63 rotation_value2 = params.s1_leaf2_angle;
64 frac = 0.9;
65 leaf_curve = leaf_width * 0.25;
66 x_adj = 0;
67
68 } else {
69 leaf_length = params.s1_leaf_size3.x;
70 leaf_width = params.s1_leaf_size3.y;
71 rotation_value1 = PI_F * 0.5;
72 leaf_bend = leaf_length * 0.2;
73 rotation_value2 = params.s1_leaf3_angle;
74 frac = 0.5;
75 leaf_curve = leaf_width * 0.25;
76 x_adj = 0;
77 }
78
79 std::vector<uint> UUIDs4;
80
81 float Nx = params.s1_leaf_subdivisions.x;
82 float Ny;
83
84 if (params.s1_leaf_subdivisions.y % 2 == 0) {
85 Ny = params.s1_leaf_subdivisions.y;
86 } else {
87 Ny = params.s1_leaf_subdivisions.y + 1;
88 }
89
90
91 float dx = leaf_length / Nx;
92 float dy = leaf_width / Ny;
93
94 float A_3 = leaf_length / float(0.08); // Half waves on the leaf
95
96 // leaf wave
97 float A_2 = leaf_length / float(80); // amplitude of each leaf wave
98
99 for (int i = 0; i < Nx; i++) {
100 for (float j = 0; j < Ny; j++) {
101
102 float frac = 2 / Ny;
103 float y_frac = j / Ny;
104 float Ny_frac_1, Ny_frac_2;
105
106 if (y_frac > 0.5) {
107 Ny_frac_1 = (1 - y_frac) * 2;
108 Ny_frac_2 = Ny_frac_1 - frac;
109
110 } else if (y_frac < 0.5) {
111 Ny_frac_1 = y_frac * 2;
112 Ny_frac_2 = Ny_frac_1 + frac;
113 } else {
114 Ny_frac_1 = (1 - y_frac) * 2;
115 Ny_frac_2 = Ny_frac_1 - frac;
116 }
117
118 float x = i * dx;
119 float y = j * dy;
120 float z = 0;
121 float sx = dx;
122 float sy = dy;
123
124 float x_i = x * PI_F / (Nx * dx);
125 float sx_i = (x + sx) * PI_F / (Nx * dx);
126
127 float z_1 = (x * PI_F) / ((Nx * dx) / (A_3));
128 float z_2 = ((x + sx) * PI_F) / ((Nx * dx) / (A_3));
129
130 float leaf_wave_1;
131 float leaf_wave_2;
132 float leaf_wave_3;
133 float leaf_wave_4;
134
135 if (j == 0) {
136 leaf_wave_1 = A_2 * sin(z_1);
137 leaf_wave_2 = A_2 * sin(z_2);
138 } else {
139 leaf_wave_1 = -leaf_curve * Ny_frac_1;
140 leaf_wave_2 = -leaf_curve * Ny_frac_1;
141 }
142
143 z = leaf_bend * sin(x_i) + leaf_wave_1;
144 vec3 v0(x, y, z);
145
146 z = leaf_bend * sin(sx_i) + leaf_wave_2;
147 vec3 v1(x + sx, y, z);
148
149 if (j == Ny - 1) {
150 leaf_wave_3 = A_2 * sin(z_2);
151 leaf_wave_4 = A_2 * sin(z_1);
152 } else {
153 leaf_wave_3 = -leaf_curve * Ny_frac_2;
154 leaf_wave_4 = -leaf_curve * Ny_frac_2;
155 }
156
157 z = leaf_bend * sin(sx_i) + leaf_wave_3;
158 vec3 v2(x + sx, y + sy, z);
159
160 z = leaf_bend * sin(x_i) + leaf_wave_4;
161 vec3 v3(x, y + sy, z);
162
163 vec2 uv0(x / (Nx * dx), y / (leaf_width));
164 vec2 uv1((x + sx) / (Nx * dx), y / (leaf_width));
165 vec2 uv2((x + sx) / (Nx * dx), (y + sy) / (leaf_width));
166 vec2 uv3(x / (Nx * dx), (y + sy) / (leaf_width));
167
168 UUIDs4.push_back(context->addTriangle(v0, v1, v2, params.s1_leaf_texture_file.c_str(), uv0, uv1, uv2));
169 UUIDs4.push_back(context->addTriangle(v0, v2, v3, params.s1_leaf_texture_file.c_str(), uv0, uv2, uv3));
170 }
171 }
172
173 std::vector<std::vector<uint>> s1_UUID_leaf_plant;
174 s1_UUID_leaf_plant.push_back(context->copyPrimitive(UUIDs4));
175 context->deletePrimitive(UUIDs4);
176
177 vec3 translation(-x_adj, -leaf_width * 0.5, 0);
178 float rotation_1 = -rotation_value2 * PI_F / float(180);
179
180 float rotation_2 = angle + rotation_value1;
181 vec3 base = interpolateTube(node_stem, frac);
182
183 context->translatePrimitive(s1_UUID_leaf_plant.back(), translation);
184 context->rotatePrimitive(s1_UUID_leaf_plant.back(), rotation_1, "y");
185 context->rotatePrimitive(s1_UUID_leaf_plant.back(), rotation_2, "z");
186 context->translatePrimitive(s1_UUID_leaf_plant.back(), base);
187
188
189 vector<vector<vector<uint>>> s1_UUID_panicle_plant; // empty vector
190 std::vector<uint> s1_UUID_branch_plant; // empty vector
191
192 UUID_trunk.push_back(s1_UUID_stem_plant.front());
193 UUID_leaf.push_back(s1_UUID_leaf_plant);
194 UUID_fruit.push_back(s1_UUID_panicle_plant);
195 UUID_branch.push_back(s1_UUID_branch_plant);
196 }
197
198 // STAGE 2
199 } else if (params.sorghum_stage == 2) {
200
201 std::vector<vec3> node_stem;
202 vector<RGBcolor> Color_stem;
203
204 std::vector<float> radius_stem;
205
206 // map the route for the stem
207 float stem_sects = params.s2_stem_length * 0.1;
208
209 for (float n = 0; n < params.s2_stem_length + stem_sects; n = n + stem_sects) {
210 float y = 0;
211 float x = 0;
212 float z = n;
213
214 node_stem.push_back(make_vec3(x, y, z) + origin);
215 radius_stem.push_back(params.s2_stem_radius);
216 Color_stem.push_back(make_RGBcolor(0.25, 0.36, 0.19));
217 }
218
219 std::vector<std::vector<uint>> s2_UUID_stem_plant;
220 s2_UUID_stem_plant.resize(1);
221 std::vector<uint> UUID_stem = context->addTube(50, node_stem, radius_stem, Color_stem);
222 std::vector<uint> UUID_stem_top = context->addDisk(50, make_vec3(0, 0, 0), make_vec2(params.s2_stem_radius, params.s2_stem_radius), make_SphericalCoord(0, 0, 0), RGBcolor(0.302, 0.4314, 0.2392));
223
224 vec3 base_top = interpolateTube(node_stem, 1);
225 context->translatePrimitive(UUID_stem_top, base_top);
226
227 s2_UUID_stem_plant.push_back(context->copyPrimitive(UUID_stem));
228 s2_UUID_stem_plant.push_back(context->copyPrimitive(UUID_stem_top));
229 context->deletePrimitive(UUID_stem);
230 context->deletePrimitive(UUID_stem_top);
231
232 float angle = ((context->randu(0, 90) * PI_F) / float(180));
233 for (float i = 1; i < 6; i++) {
234 float leaf_length, leaf_width, rotation_value1, leaf_bend, rotation_value2, frac, leaf_curve, leaf_wave_no, leaf_wave;
235
236 if (i == 1) {
237 leaf_length = params.s2_leaf_size1.x;
238 leaf_width = params.s2_leaf_size1.y;
239 rotation_value1 = 0;
240 leaf_bend = leaf_length * 0.2;
241 rotation_value2 = 25;
242 frac = 0.98;
243 leaf_curve = leaf_width * 0.25;
244 leaf_wave_no = 50;
245 leaf_wave = 0.0125;
246
247 } else if (i == 2) {
248 leaf_length = params.s2_leaf_size2.x;
249 leaf_width = params.s2_leaf_size2.y;
250 rotation_value1 = PI_F;
251 leaf_bend = leaf_length * 0.2;
252 rotation_value2 = 50;
253 frac = 0.98;
254 leaf_curve = leaf_width * 0.5;
255 leaf_wave_no = 40;
256 leaf_wave = 0.02;
257
258 } else if (i == 3) {
259 leaf_length = params.s2_leaf_size3.x;
260 leaf_width = params.s2_leaf_size3.y;
261 rotation_value1 = PI_F + ((context->randu(0, 45) * PI_F) / float(180));
262 leaf_bend = leaf_length * 0.3;
263 rotation_value2 = 15;
264 frac = 0.75;
265 leaf_curve = leaf_width * 0.5;
266 leaf_wave_no = 40;
267 leaf_wave = 0.015;
268
269 } else if (i == 4) {
270 leaf_length = params.s2_leaf_size4.x;
271 leaf_width = params.s2_leaf_size4.y;
272 rotation_value1 = ((context->randu(0, 45) * PI_F) / float(180));
273 leaf_bend = leaf_length * 0.3;
274 rotation_value2 = 25;
275 frac = 0.5;
276 leaf_curve = leaf_width * 0.5;
277 leaf_wave_no = 40;
278 leaf_wave = 0;
279
280 } else {
281 leaf_length = params.s2_leaf_size5.x;
282 leaf_width = params.s2_leaf_size5.y;
283 rotation_value1 = PI_F + ((context->randu(0, 45) * PI_F) / float(180));
284 leaf_bend = leaf_length * 0.3;
285 rotation_value2 = 10;
286 frac = 0.25;
287 leaf_curve = leaf_width * 0.5;
288 leaf_wave_no = 40;
289 leaf_wave = 0;
290 }
291
292 std::vector<std::vector<uint>> s2_UUID_leaf_plant;
293
294 std::vector<uint> UUIDs4;
295
296 float Nx = params.s2_leaf_subdivisions.x;
297 float Ny;
298
299 if (params.s2_leaf_subdivisions.y % 2 == 0) {
300 Ny = params.s2_leaf_subdivisions.y;
301 } else {
302 Ny = params.s2_leaf_subdivisions.y + 1;
303 }
304
305 float dx = leaf_length / Nx;
306 float dy = leaf_width / Ny;
307
308 float A_3 = leaf_length * leaf_wave_no; // Half waves on the leaf
309
310 // leaf wave
311 float A_2 = leaf_length * leaf_wave; // amplitude of each leaf wave
312
313 for (int i = 0; i < Nx; i++) {
314 for (float j = 0; j < Ny; j++) {
315
316 float frac = 2 / Ny;
317 float y_frac = j / Ny;
318 float Ny_frac_1, Ny_frac_2;
319
320 if (y_frac > 0.5) {
321 Ny_frac_1 = (1 - y_frac) * 2;
322 Ny_frac_2 = Ny_frac_1 - frac;
323
324 } else if (y_frac < 0.5) {
325 Ny_frac_1 = y_frac * 2;
326 Ny_frac_2 = Ny_frac_1 + frac;
327 } else {
328 Ny_frac_1 = (1 - y_frac) * 2;
329 Ny_frac_2 = Ny_frac_1 - frac;
330 }
331
332 float x = i * dx;
333 float y = j * dy;
334 float z = 0;
335 float sx = dx;
336 float sy = dy;
337
338 float x_i = x * PI_F / (Nx * dx);
339 float sx_i = (x + sx) * PI_F / (Nx * dx);
340
341 float z_1 = (x * PI_F) / ((Nx * dx) / (A_3));
342 float z_2 = ((x + sx) * PI_F) / ((Nx * dx) / (A_3));
343
344 float leaf_wave_1;
345 float leaf_wave_2;
346 float leaf_wave_3;
347 float leaf_wave_4;
348
349 if (j == 0) {
350 leaf_wave_1 = A_2 * sin(z_1);
351 leaf_wave_2 = A_2 * sin(z_2);
352 } else {
353 leaf_wave_1 = -leaf_curve * Ny_frac_1;
354 leaf_wave_2 = -leaf_curve * Ny_frac_1;
355 }
356
357 z = leaf_bend * sin(x_i) + leaf_wave_1;
358 vec3 v0(x, y, z);
359
360 z = leaf_bend * sin(sx_i) + leaf_wave_2;
361 vec3 v1(x + sx, y, z);
362
363 if (j == Ny - 1) {
364 leaf_wave_3 = A_2 * sin(z_2);
365 leaf_wave_4 = A_2 * sin(z_1);
366 } else {
367 leaf_wave_3 = -leaf_curve * Ny_frac_2;
368 leaf_wave_4 = -leaf_curve * Ny_frac_2;
369 }
370
371 z = leaf_bend * sin(sx_i) + leaf_wave_3;
372 vec3 v2(x + sx, y + sy, z);
373
374 z = leaf_bend * sin(x_i) + leaf_wave_4;
375 vec3 v3(x, y + sy, z);
376
377 vec2 uv0(x / (Nx * dx), y / (leaf_width));
378 vec2 uv1((x + sx) / (Nx * dx), y / (leaf_width));
379 vec2 uv2((x + sx) / (Nx * dx), (y + sy) / (leaf_width));
380 vec2 uv3(x / (Nx * dx), (y + sy) / (leaf_width));
381
382 UUIDs4.push_back(context->addTriangle(v0, v1, v2, params.s2_leaf_texture_file.c_str(), uv0, uv1, uv2));
383 UUIDs4.push_back(context->addTriangle(v0, v2, v3, params.s2_leaf_texture_file.c_str(), uv0, uv2, uv3));
384 }
385 }
386
387 s2_UUID_leaf_plant.push_back(context->copyPrimitive(UUIDs4));
388 context->deletePrimitive(UUIDs4);
389
390 vec3 translation(-0.00015 * rotation_value2, -leaf_width * 0.5, 0); // adjustment v0 amplitude,v1 radius v2 leaf_length
391 float rotation_1 = -rotation_value2 * PI_F / float(180);
392
393 float rotation_2 = angle + rotation_value1;
394 vec3 base = interpolateTube(node_stem, frac);
395
396 context->translatePrimitive(s2_UUID_leaf_plant.back(), translation);
397 context->rotatePrimitive(s2_UUID_leaf_plant.back(), rotation_1, "y");
398 context->rotatePrimitive(s2_UUID_leaf_plant.back(), rotation_2, "z");
399 context->translatePrimitive(s2_UUID_leaf_plant.back(), base);
400
401 vector<vector<vector<uint>>> s2_UUID_panicle_plant; // empty vector
402 std::vector<uint> s2_UUID_branch_plant; // empty vector
403
404 UUID_trunk.push_back(s2_UUID_stem_plant.front());
405 UUID_leaf.push_back(s2_UUID_leaf_plant);
406 UUID_fruit.push_back(s2_UUID_panicle_plant);
407 UUID_branch.push_back(s2_UUID_branch_plant);
408 }
409
410 }
411
412 // STAGE 3
413 else if (params.sorghum_stage == 3) {
414 // STEM
415 std::vector<vec3> node_stem;
416 vector<RGBcolor> Color_stem;
417 std::vector<float> radius_stem;
418
419 // map the route for the stem
420 float stem_sects = params.s3_stem_length * 0.1;
421
422 for (float n = 0; n < params.s3_stem_length + stem_sects; n = n + stem_sects) {
423 float y = 0;
424 float x = 0;
425 float z = n;
426
427 node_stem.push_back(make_vec3(x, y, z) + origin);
428 radius_stem.push_back(params.s3_stem_radius);
429 Color_stem.push_back(make_RGBcolor(0.302, 0.4314, 0.2392));
430 }
431
432 std::vector<uint> s3_UUID_stem_plant = context->addTube(params.s3_stem_subdivisions, node_stem, radius_stem, Color_stem);
433
434 // THE LEAVES
435
436 int nodes_no = params.s3_number_of_leaves;
437
438 float rotation_x1 = (context->randu(0, 360) * PI_F) / float(180); // inclination rotation, different for each plant
439 std::vector<std::vector<uint>> s3_UUID_leaf_plant;
440
441 for (int i = 1; i < (nodes_no + 1); i++) {
442
443 std::vector<uint> UUIDs4;
444
445 float Nx = params.s3_leaf_subdivisions.x;
446 float Ny;
447
448 if (params.s3_leaf_subdivisions.y % 2 == 0) {
449 Ny = params.s3_leaf_subdivisions.y;
450 } else {
451 Ny = params.s3_leaf_subdivisions.y + 1;
452 }
453
454 float x;
455
456 if (i >= (nodes_no - 1) || i == 1) {
457 x = 0.75;
458 } else {
459 x = 1;
460 }
461
462 float dx = params.s3_leaf_size.x * x / Nx;
463 float dy = params.s3_leaf_size.y / Ny;
464
465 float A_3 = params.s3_leaf_size.x / float(0.08); // Half waves on the leaf
466
467 // leaf wave
468 float A_2 = params.s3_leaf_size.x / float(80); // amplitude of each leaf wave
469 float leaf_amplitude = params.s3_leaf_size.x / float(6);
470
471 for (int i = 0; i < Nx; i++) {
472 for (float j = 0; j < Ny; j++) {
473
474 float frac = 2 / Ny;
475 float y_frac = j / Ny;
476 float Ny_frac_1, Ny_frac_2;
477
478 if (y_frac > 0.5) {
479 Ny_frac_1 = (1 - y_frac) * 2;
480 Ny_frac_2 = Ny_frac_1 - frac;
481
482 } else if (y_frac < 0.5) {
483 Ny_frac_1 = y_frac * 2;
484 Ny_frac_2 = Ny_frac_1 + frac;
485 } else {
486 Ny_frac_1 = (1 - y_frac) * 2;
487 Ny_frac_2 = Ny_frac_1 - frac;
488 }
489
490 float x = i * dx;
491 float y = j * dy;
492 float z = 0;
493 float sx = dx;
494 float sy = dy;
495
496 float x_i = x * PI_F / (Nx * dx);
497 float sx_i = (x + sx) * PI_F / (Nx * dx);
498
499 float z_1 = (x * PI_F) / ((Nx * dx) / (A_3));
500 float z_2 = ((x + sx) * PI_F) / ((Nx * dx) / (A_3));
501
502 float leaf_wave_1;
503 float leaf_wave_2;
504 float leaf_wave_3;
505 float leaf_wave_4;
506
507 if (j == 0) {
508 leaf_wave_1 = A_2 * sin(z_1);
509 leaf_wave_2 = A_2 * sin(z_2);
510 } else {
511 leaf_wave_1 = -params.s3_leaf_size.y * 0.425 * Ny_frac_1;
512 leaf_wave_2 = -params.s3_leaf_size.y * 0.425 * Ny_frac_1;
513 }
514
515 z = leaf_amplitude * sin(x_i) + leaf_wave_1;
516 vec3 v0(x, y, z);
517
518 z = leaf_amplitude * sin(sx_i) + leaf_wave_2;
519 vec3 v1(x + sx, y, z);
520
521 if (j == Ny - 1) {
522 leaf_wave_3 = A_2 * sin(z_2);
523 leaf_wave_4 = A_2 * sin(z_1);
524 } else {
525 leaf_wave_3 = -params.s3_leaf_size.y * 0.425 * Ny_frac_2;
526 leaf_wave_4 = -params.s3_leaf_size.y * 0.425 * Ny_frac_2;
527 }
528
529 z = leaf_amplitude * sin(sx_i) + leaf_wave_3;
530 vec3 v2(x + sx, y + sy, z);
531
532 z = leaf_amplitude * sin(x_i) + leaf_wave_4;
533 vec3 v3(x, y + sy, z);
534
535 vec2 uv0(x / (Nx * dx), y / (params.s3_leaf_size.y));
536 vec2 uv1((x + sx) / (Nx * dx), y / (params.s3_leaf_size.y));
537 vec2 uv2((x + sx) / (Nx * dx), (y + sy) / (params.s3_leaf_size.y));
538 vec2 uv3(x / (Nx * dx), (y + sy) / (params.s3_leaf_size.y));
539
540 UUIDs4.push_back(context->addTriangle(v0, v1, v2, params.s3_leaf_texture_file.c_str(), uv0, uv1, uv2));
541 UUIDs4.push_back(context->addTriangle(v0, v2, v3, params.s3_leaf_texture_file.c_str(), uv0, uv2, uv3));
542 }
543 }
544
545
546 s3_UUID_leaf_plant.push_back(context->copyPrimitive(UUIDs4));
547 context->deletePrimitive(UUIDs4);
548
549 float frac;
550
551 if (i == 1) {
552
553 frac = 1;
554 } else {
555
556 frac = 1 - ((i - (context->randu() / float(2))) / float((nodes_no + 1)));
557 }
558
559 vec3 base = interpolateTube(node_stem, frac);
560 float rotation_1 = -(params.s3_mean_leaf_angle * PI_F / float(180)) - (context->randu(0, 5) * PI_F) / float(180);
561 float rotation_x2 = (context->randu(0, 45) * PI_F) / float(180);
562 float rotation_2 = rotation_x1 + rotation_x2;
563 float rotation_3 = rotation_2 + PI_F; //
564 vec3 translation(-params.s3_stem_radius * 2.8, -0.9 / (2 / float(params.s3_leaf_size.y)), 0); // adjustment
565
566 if (i % 2 != 0) {
567 context->translatePrimitive(s3_UUID_leaf_plant.back(), translation);
568 context->rotatePrimitive(s3_UUID_leaf_plant.back(), rotation_1, "y");
569 context->rotatePrimitive(s3_UUID_leaf_plant.back(), rotation_2, "z");
570 context->translatePrimitive(s3_UUID_leaf_plant.back(), base);
571
572 } else {
573 context->translatePrimitive(s3_UUID_leaf_plant.back(), translation);
574 context->rotatePrimitive(s3_UUID_leaf_plant.back(), rotation_1, "y");
575 context->rotatePrimitive(s3_UUID_leaf_plant.back(), rotation_3, "z");
576 context->translatePrimitive(s3_UUID_leaf_plant.back(), base);
577 }
578 }
579
580 vector<vector<vector<uint>>> s3_UUID_panicle_plant; // empty vector
581 std::vector<uint> s3_UUID_branch_plant; // empty vector
582
583 UUID_trunk.push_back(s3_UUID_stem_plant);
584 UUID_leaf.push_back(s3_UUID_leaf_plant);
585 UUID_fruit.push_back(s3_UUID_panicle_plant);
586 UUID_branch.push_back(s3_UUID_branch_plant);
587
588 }
589 // STAGE 4
590 else if (params.sorghum_stage == 4) {
591 // THE STEM
592 std::vector<vec3> node_stem;
593
594 vector<RGBcolor> Color_stem;
595
596 std::vector<float> radius_stem;
597
598 // map the route for the stem
599 float stem_sects = params.s4_stem_length * 0.1;
600
601 for (float n = 0; n < params.s4_stem_length + stem_sects; n = n + stem_sects) {
602 float y = 0;
603 float x = 0;
604 float z = n;
605
606 node_stem.push_back(make_vec3(x, y, z) + origin);
607 radius_stem.push_back(params.s4_stem_radius);
608 Color_stem.push_back(make_RGBcolor(0.302, 0.4314, 0.2392));
609 }
610
611 std::vector<uint> s4_UUID_stem_plant = context->addTube(params.s4_stem_subdivisions, node_stem, radius_stem, Color_stem); // 50
612
613 // THE PANICLE
614
615 vector<vector<vector<uint>>> s4_UUID_panicle_plant;
616 s4_UUID_panicle_plant.resize(1);
617 vector<RGBcolor> Color_panicle_stalk;
618 std::vector<vec3> nodes_panicle_stalk;
619 std::vector<float> radius_panicle_stalk;
620
621 // The panicle stalk (the stem of the panicle)
622 float m = 0.125;
623 for (float n = 0; n < m; n = n + 0.0125) {
624 float y = 0;
625 float x = 0;
626 float z = n;
627
628 nodes_panicle_stalk.push_back(make_vec3(x, y, z));
629 radius_panicle_stalk.push_back(params.s4_stem_radius);
630
631 Color_panicle_stalk.push_back(make_RGBcolor(0.302, 0.4314, 0.2392));
632 }
633
634 std::vector<uint> UUID1 = context->addTube(params.s4_stem_subdivisions, nodes_panicle_stalk, radius_panicle_stalk, Color_panicle_stalk);
635
636 s4_UUID_panicle_plant.front().push_back(context->copyPrimitive(UUID1));
637 context->deletePrimitive(UUID1);
638
639 // now the panicle
640 std::vector<vec3> nodes_panicle;
641 std::vector<float> radius_panicle;
642 float adj = 20; // scale factor to match the length of meters
643 float width_panicle = params.s4_panicle_size.y * 10 * adj;
644
645 for (float n = 0; n < (width_panicle); n++) { // Ball-shaped tubes which form the panicle
646 float x = 0;
647 float y = 0;
648 float dz = n * (0.01);
649 float z = dz;
650 float angle = n * PI_F / width_panicle;
651 float dr = 0.01 * sin(angle);
652
653 nodes_panicle.push_back(make_vec3(x, y, z));
654 radius_panicle.push_back(dr);
655 }
656
657 std::vector<uint> UUIDs2 = context->addTube(params.s4_panicle_subdivisions, nodes_panicle, radius_panicle, params.s4_seed_texture_file.c_str());
658
659 float z_value = 0;
660 float di = 0;
661
662 for (int i = (params.s4_panicle_size.x * adj) + 2; i > -1; i--) {
663 std::vector<uint> UUIDs2_copy = context->copyPrimitive(UUIDs2);
664
665 float rotation_angle;
666
667 if (i > (((params.s4_panicle_size.x * adj) + 2) / float(3))) {
668 rotation_angle = 0.26;
669 } else {
670 rotation_angle = i * 0.0867;
671 }
672 float dz = 0.032;
673
674 z_value = z_value + dz;
675 vec3 tra1(0, 0, z_value - dz);
676 vec3 base = interpolateTube(nodes_panicle_stalk, 0.05);
677 float rot1 = rotation_angle;
678
679 context->rotatePrimitive(UUIDs2_copy, rot1, "y");
680 context->translatePrimitive(UUIDs2_copy, base);
681 context->translatePrimitive(UUIDs2_copy, tra1);
682 s4_UUID_panicle_plant.front().push_back(UUIDs2_copy);
683
684 float i_value_1, i_value_2;
685
686 if (di == 0) {
687 i_value_1 = 6;
688 i_value_2 = 60;
689 di = 1;
690 } else {
691 i_value_1 = 5;
692 i_value_2 = 72;
693 di = 0;
694 }
695
696 for (int ii = 0; ii < i_value_1; ii++) {
697 s4_UUID_panicle_plant.front().push_back(context->copyPrimitive(UUIDs2_copy));
698 float rot2 = ii * i_value_2 * PI_F / float(180);
699 context->rotatePrimitive(s4_UUID_panicle_plant.front().back(), rot2, "z");
700 }
701 };
702
703 context->deletePrimitive(UUIDs2);
704 vec3 V_1 = interpolateTube(node_stem, 1);
705 context->translatePrimitive(flatten(s4_UUID_panicle_plant), V_1);
706
707 // THE LEAVES
708
709 int nodes_no = params.s4_number_of_leaves;
710
711 float rotation_x1 = (context->randu(0, 360) * PI_F) / float(180); // inclination rotation, different for each plant
712 std::vector<std::vector<uint>> s4_UUID_leaf_plant;
713
714 for (int i = 1; i < (nodes_no + 1); i++) {
715
716 std::vector<uint> UUIDs4;
717
718 float Nx = params.s4_leaf_subdivisions.x;
719 float Ny;
720
721 if (params.s4_leaf_subdivisions.y % 2 == 0) {
722 Ny = params.s4_leaf_subdivisions.y;
723 } else {
724 Ny = params.s4_leaf_subdivisions.y + 1;
725 }
726
727 float x;
728
729 if (i >= (nodes_no - 1) || i == 1) {
730
731 x = 0.75;
732 } else {
733
734 x = 1;
735 }
736
737 float dx = params.s4_leaf_size.x * x / Nx;
738 float dy = params.s4_leaf_size.y / Ny;
739
740 float A_3 = params.s4_leaf_size.x / float(0.08); // Half waves on the leaf 10
741
742 // leaf wave
743 float A_2 = params.s4_leaf_size.x / float(80); // amplitude of each leaf wave
744
745 float leaf_amplitude = params.s4_leaf_size.x / float(6);
746
747 for (int i = 0; i < Nx; i++) {
748 for (float j = 0; j < Ny; j++) {
749
750 float frac = 2 / Ny;
751 float y_frac = j / Ny;
752 float Ny_frac_1, Ny_frac_2;
753
754 if (y_frac > 0.5) {
755 Ny_frac_1 = (1 - y_frac) * 2;
756 Ny_frac_2 = Ny_frac_1 - frac;
757
758 } else if (y_frac < 0.5) {
759 Ny_frac_1 = y_frac * 2;
760 Ny_frac_2 = Ny_frac_1 + frac;
761 } else {
762 Ny_frac_1 = (1 - y_frac) * 2;
763 Ny_frac_2 = Ny_frac_1 - frac;
764 }
765
766 float x = i * dx;
767 float y = j * dy;
768 float z = 0;
769 float sx = dx;
770 float sy = dy;
771
772 float x_i = x * PI_F / (Nx * dx);
773 float sx_i = (x + sx) * PI_F / (Nx * dx);
774
775 float z_1 = (x * PI_F) / ((Nx * dx) / A_3);
776 float z_2 = ((x + sx) * PI_F) / ((Nx * dx) / A_3);
777
778 float leaf_wave_1;
779 float leaf_wave_2;
780 float leaf_wave_3;
781 float leaf_wave_4;
782
783 if (j == 0) {
784 leaf_wave_1 = A_2 * sin(z_1);
785 leaf_wave_2 = A_2 * sin(z_2);
786 } else {
787 leaf_wave_1 = -params.s4_leaf_size.y * 0.425 * Ny_frac_1;
788 leaf_wave_2 = -params.s4_leaf_size.y * 0.425 * Ny_frac_1;
789 }
790
791 z = leaf_amplitude * sin(x_i) + leaf_wave_1;
792 vec3 v0(x, y, z);
793
794 z = leaf_amplitude * sin(sx_i) + leaf_wave_2;
795 vec3 v1(x + sx, y, z);
796
797 if (j == Ny - 1) {
798 leaf_wave_3 = A_2 * sin(z_2);
799 leaf_wave_4 = A_2 * sin(z_1);
800 } else {
801 leaf_wave_3 = -params.s4_leaf_size.y * 0.425 * Ny_frac_2;
802 leaf_wave_4 = -params.s4_leaf_size.y * 0.425 * Ny_frac_2;
803 }
804
805 z = leaf_amplitude * sin(sx_i) + leaf_wave_3;
806 vec3 v2(x + sx, y + sy, z);
807
808 z = leaf_amplitude * sin(x_i) + leaf_wave_4;
809 vec3 v3(x, y + sy, z);
810
811 vec2 uv0(x / (Nx * dx), y / float(params.s4_leaf_size.y));
812 vec2 uv1((x + sx) / (Nx * dx), y / float(params.s4_leaf_size.y));
813 vec2 uv2((x + sx) / (Nx * dx), (y + sy) / float(params.s4_leaf_size.y));
814 vec2 uv3(x / (Nx * dx), (y + sy) / float(params.s4_leaf_size.y));
815
816 UUIDs4.push_back(context->addTriangle(v0, v1, v2, params.s4_leaf_texture_file.c_str(), uv0, uv1, uv2));
817 UUIDs4.push_back(context->addTriangle(v0, v2, v3, params.s4_leaf_texture_file.c_str(), uv0, uv2, uv3));
818 }
819 }
820
821
822 s4_UUID_leaf_plant.push_back(context->copyPrimitive(UUIDs4));
823 context->deletePrimitive(UUIDs4);
824
825 float frac;
826
827 if (i == 1) {
828 frac = 0.9;
829 } else {
830 frac = (1 - ((i - (context->randu() / float(2))) / float((nodes_no + 1) * 1.2))) - 0.15;
831 }
832
833 vec3 base = interpolateTube(node_stem, frac);
834 float rotation_1 = -(params.s4_mean_leaf_angle * PI_F / float(180)) - (context->randu(0, 5) * PI_F) / float(180);
835 float rotation_x2 = (context->randu(0, 45) * PI_F) / float(180);
836 float rotation_2 = rotation_x1 + rotation_x2;
837 float rotation_3 = rotation_2 + PI_F; //
838 vec3 translation(-params.s4_stem_radius * 2, -0.9 / (2 / float(params.s4_leaf_size.y)), 0); // adjustment
839
840 if (i % 2 != 0) {
841 context->translatePrimitive(s4_UUID_leaf_plant.back(), translation);
842 context->rotatePrimitive(s4_UUID_leaf_plant.back(), rotation_1, "y");
843 context->rotatePrimitive(s4_UUID_leaf_plant.back(), rotation_2, "z");
844 context->translatePrimitive(s4_UUID_leaf_plant.back(), base);
845
846 } else {
847 context->translatePrimitive(s4_UUID_leaf_plant.back(), translation);
848 context->rotatePrimitive(s4_UUID_leaf_plant.back(), rotation_1, "y");
849 context->rotatePrimitive(s4_UUID_leaf_plant.back(), rotation_3, "z");
850 context->translatePrimitive(s4_UUID_leaf_plant.back(), base);
851 }
852 }
853
854 std::vector<uint> s4_UUID_branch_plant; // empty vector
855
856 UUID_trunk.push_back(s4_UUID_stem_plant);
857 UUID_fruit.push_back(s4_UUID_panicle_plant);
858 UUID_leaf.push_back(s4_UUID_leaf_plant);
859 UUID_branch.push_back(s4_UUID_branch_plant);
860
861
862 } else { // STAGE 5
863 // THE STEM
864 std::vector<vec3> nodes_stem;
865
866 std::vector<float> radius_stem;
867 vector<RGBcolor> Color_stem;
868
869 float Nx_stem = params.s5_stem_subdivisions;
870 float dx = 1.f / float(Nx_stem);
871
872 for (float n = 0; n < params.s5_stem_length * Nx_stem; n++) {
873 float mid_height = params.s5_stem_length * 0.5;
874 float nx = n * dx;
875 float i = nx * (180 / float(params.s5_stem_length)) * PI_F / float(180);
876 float i_mid = (mid_height) * (180 / float(params.s5_stem_length)) * PI_F / float(180);
877 float x_mid = -params.s5_stem_bend * sin(i_mid);
878 float x1, x;
879 if (nx <= mid_height) {
880 x = 0;
881 } else {
882 x1 = -params.s5_stem_bend * sin(i);
883 x = x1 - x_mid;
884 }
885 float y = 0;
886
887 float z = nx;
888
889 nodes_stem.push_back(make_vec3(x, y, z) + origin);
890
891 radius_stem.push_back(params.s5_stem_radius);
892
893 Color_stem.push_back(make_RGBcolor(0.302, 0.4314, 0.2392));
894 }
895
896 std::vector<uint> s5_UUID_stem_plant = context->addTube(params.s5_stem_subdivisions, nodes_stem, radius_stem,
897 Color_stem); // 50
898
899
900 // THE PANICLE
901 // a std::vector<std::vector<std::vector<uint> > > s5_UUID_panicle_plant;
902 // a s5_UUID_panicle_plant.resize(1);
903
904 vector<vector<vector<uint>>> s5_UUID_panicle_plant;
905 s5_UUID_panicle_plant.resize(1);
906
907 vector<RGBcolor> Color_panicle_stalk;
908 std::vector<vec3> nodes_panicle_stalk;
909 std::vector<float> radius_panicle_stalk;
910
911 // The panicle stalk (the stem of the panicle)
912 float m = 0.125;
913 for (float n = 0; n < m; n = n + 0.0125) {
914 float y = 0;
915 float x = 0;
916 float z = n;
917
918 nodes_panicle_stalk.push_back(make_vec3(x, y, z));
919 radius_panicle_stalk.push_back(params.s5_stem_radius);
920 Color_panicle_stalk.push_back(make_RGBcolor(0.302, 0.4314, 0.2392));
921 }
922
923 std::vector<uint> UUID1 = context->addTube(params.s5_stem_subdivisions, nodes_panicle_stalk, radius_panicle_stalk, Color_panicle_stalk);
924
925 s5_UUID_panicle_plant.front().push_back(context->copyPrimitive(UUID1));
926 context->deletePrimitive(UUID1);
927
928 // now the panicle
929 std::vector<vec3> nodes_panicle;
930 std::vector<float> radius_panicle;
931 float adj = 20; // scale factor to match the length of meters
932 float width_panicle = params.s5_panicle_size.y * 10 * adj;
933
934 for (float n = 0; n < width_panicle; n++) {
935 float x = 0;
936 float y = 0;
937 float dz = n * (0.01);
938 float z = dz;
939 float angle = n * PI_F / width_panicle;
940 float dr = 0.01 * sin(angle);
941
942 nodes_panicle.push_back(make_vec3(x, y, z));
943 radius_panicle.push_back(dr);
944 }
945
946 std::vector<uint> UUIDs2 = context->addTube(params.s5_panicle_subdivisions, nodes_panicle, radius_panicle, params.s5_seed_texture_file.c_str());
947
948 float z_value = 0;
949
950 float di = 0;
951
952 for (int i = (params.s5_panicle_size.x * adj) + 2; i > -1; i--) {
953
954
955 std::vector<uint> UUIDs_copy = context->copyPrimitive(UUIDs2);
956
957 float rotation_angle;
958
959 if (i > (((params.s5_panicle_size.x * adj) + 2) / float(3))) {
960 rotation_angle = 0.26;
961 } else {
962 rotation_angle = i * 0.0867;
963 }
964 float dz = 0.032;
965
966 z_value = z_value + dz;
967 vec3 tra1(0, 0, z_value - dz);
968 vec3 base = interpolateTube(nodes_panicle_stalk, 0.05);
969 float rot1 = rotation_angle;
970
971 context->rotatePrimitive(UUIDs_copy, rot1, "y");
972 context->translatePrimitive(UUIDs_copy, base);
973 context->translatePrimitive(UUIDs_copy, tra1);
974
975
976 s5_UUID_panicle_plant.front().push_back(UUIDs_copy);
977
978 float i_value_1, i_value_2;
979
980 if (di == 0) {
981 i_value_1 = 6;
982 i_value_2 = 60;
983 di = 1;
984 } else {
985 i_value_1 = 5;
986 i_value_2 = 72;
987 di = 0;
988 }
989
990 for (int ii = 0; ii < i_value_1; ii++) {
991 s5_UUID_panicle_plant.front().push_back(context->copyPrimitive(UUIDs_copy));
992 float rot2 = ii * i_value_2 * PI_F / float(180);
993 context->rotatePrimitive(s5_UUID_panicle_plant.front().back(), rot2, "z");
994 }
995 };
996
997
998 context->deletePrimitive(UUIDs2);
999 ;
1000 vec3 V_1 = interpolateTube(nodes_stem, 1);
1001 vec3 V_2 = interpolateTube(nodes_stem, 0.95);
1002 vec3 V_3 = V_1 - V_2;
1003
1004 float Z = cart2sphere(V_3).zenith;
1005
1006 context->rotatePrimitive(flatten(s5_UUID_panicle_plant), Z, "y");
1007
1008 context->translatePrimitive(flatten(s5_UUID_panicle_plant), V_1);
1009
1010
1011 // THE LEAVES
1012
1013 int nodes_no = params.s5_number_of_leaves;
1014
1015
1016 float rotation_x1 = (context->randu(0, 360) * PI_F) / float(180); // inclination rotation, different for each plant
1017 std::vector<std::vector<uint>> s5_UUID_leaf_plant;
1018
1019 for (int i = 1; i < (nodes_no + 1); i++) {
1020
1021 std::vector<uint> UUIDs4;
1022
1023 float Nx = params.s5_leaf_subdivisions.x;
1024 float Ny;
1025
1026 if (params.s5_leaf_subdivisions.y % 2 == 0) {
1027 Ny = params.s5_leaf_subdivisions.y;
1028 } else {
1029 Ny = params.s5_leaf_subdivisions.y + 1;
1030 }
1031
1032 float x;
1033
1034 if (i >= (nodes_no - 1) || i == 1) {
1035
1036 x = 0.75;
1037 } else {
1038
1039 x = 1;
1040 }
1041
1042
1043 float dx = params.s5_leaf_size.x * x / Nx;
1044 float dy = params.s5_leaf_size.y / Ny;
1045
1046 float A_3 = params.s5_leaf_size.x / float(0.08); // Half waves on the leaf
1047 float A_2 = params.s5_leaf_size.x / float(90); //
1048 float leaf_amplitude = params.s5_leaf_size.x / float(5); //
1049
1050 for (int i = 0; i < Nx; i++) {
1051 for (float j = 0; j < Ny; j++) {
1052
1053 float x = i * dx;
1054 float y = j * dy;
1055 float z = 0;
1056 float sx = dx;
1057 float sy = dy;
1058
1059 float x_i = x * PI_F / (Nx * dx);
1060 float sx_i = (x + sx) * PI_F / (Nx * dx);
1061
1062 float z_1 = (x * PI_F) / ((Nx * dx) / A_3);
1063 float z_2 = ((x + sx) * PI_F) / ((Nx * dx) / A_3);
1064
1065 float leaf_wave_1;
1066 float leaf_wave_2;
1067 float leaf_wave_3;
1068 float leaf_wave_4;
1069
1070 if (j == 0) {
1071 leaf_wave_1 = A_2 * sin(z_1);
1072 leaf_wave_2 = A_2 * sin(z_2);
1073 } else {
1074 leaf_wave_1 = 0;
1075 leaf_wave_2 = 0;
1076 }
1077
1078 z = leaf_amplitude * sin(x_i) + leaf_wave_1;
1079 vec3 v0(x, y, z);
1080
1081 z = leaf_amplitude * sin(sx_i) + leaf_wave_2;
1082 vec3 v1(x + sx, y, z);
1083
1084 if (j == Ny - 1) {
1085 leaf_wave_3 = A_2 * sin(z_2);
1086 leaf_wave_4 = A_2 * sin(z_1);
1087 } else {
1088 leaf_wave_3 = 0;
1089 leaf_wave_4 = 0;
1090 }
1091
1092 z = leaf_amplitude * sin(sx_i) + leaf_wave_3;
1093 vec3 v2(x + sx, y + sy, z);
1094
1095 z = leaf_amplitude * sin(x_i) + leaf_wave_4;
1096 vec3 v3(x, y + sy, z);
1097
1098 vec2 uv0(x / (Nx * dx), y / float(params.s5_leaf_size.y));
1099 vec2 uv1((x + sx) / (Nx * dx), y / float(params.s5_leaf_size.y));
1100 vec2 uv2((x + sx) / (Nx * dx), (y + sy) / float(params.s5_leaf_size.y));
1101 vec2 uv3(x / (Nx * dx), (y + sy) / float(params.s5_leaf_size.y));
1102
1103 UUIDs4.push_back(context->addTriangle(v0, v1, v2, params.s5_leaf_texture_file.c_str(), uv0, uv1, uv2));
1104 UUIDs4.push_back(context->addTriangle(v0, v2, v3, params.s5_leaf_texture_file.c_str(), uv0, uv2, uv3));
1105 }
1106 }
1107
1108 s5_UUID_leaf_plant.push_back(context->copyPrimitive(UUIDs4));
1109 context->deletePrimitive(UUIDs4);
1110
1111 float frac;
1112
1113 if (i == 1) {
1114
1115 frac = 0.9;
1116 } else {
1117
1118 frac = (1 - ((i - (context->randu() / float(2))) / float((nodes_no + 1) * 1.2))) - 0.15;
1119 }
1120
1121 vec3 base = interpolateTube(nodes_stem, frac);
1122 float rotation_1 = -(params.s5_mean_leaf_angle * PI_F / float(180)) - (context->randu(0, 10) * PI_F) / float(180);
1123 float rotation_x2 = (context->randu(0, 45) * PI_F) / float(180);
1124 float rotation_2 = rotation_x1 + rotation_x2;
1125 float rotation_3 = rotation_2 + PI_F; //
1126 vec3 translation(0, -0.9 / (2 / float(params.s5_leaf_size.y)), 0); // adjustment
1127
1128 if (i % 2 != 0) {
1129 context->translatePrimitive(s5_UUID_leaf_plant.back(), translation);
1130 context->rotatePrimitive(s5_UUID_leaf_plant.back(), rotation_1, "y");
1131 context->rotatePrimitive(s5_UUID_leaf_plant.back(), rotation_2, "z");
1132 context->translatePrimitive(s5_UUID_leaf_plant.back(), base);
1133
1134 } else {
1135 context->translatePrimitive(s5_UUID_leaf_plant.back(), translation);
1136 context->rotatePrimitive(s5_UUID_leaf_plant.back(), rotation_1, "y");
1137 context->rotatePrimitive(s5_UUID_leaf_plant.back(), rotation_3, "z");
1138 context->translatePrimitive(s5_UUID_leaf_plant.back(), base);
1139 }
1140 }
1141
1142 float plant_rotation = (context->randu(0, 360) * PI_F) / float(180);
1143
1144 context->rotatePrimitive(s5_UUID_stem_plant, plant_rotation, origin, make_vec3(0, 0, 1));
1145 context->rotatePrimitive(flatten(s5_UUID_panicle_plant), plant_rotation, origin, make_vec3(0, 0, 1));
1146 context->rotatePrimitive(flatten(s5_UUID_leaf_plant), plant_rotation, origin, make_vec3(0, 0, 1));
1147
1148 std::vector<uint> s5_UUID_branch_plant; // empty vector
1149
1150 UUID_trunk.push_back(s5_UUID_stem_plant);
1151 UUID_fruit.push_back(s5_UUID_panicle_plant);
1152 UUID_leaf.push_back(s5_UUID_leaf_plant);
1153 UUID_branch.push_back(s5_UUID_branch_plant);
1154 }
1155
1156 return UUID_leaf.size() - 1;
1157};