149 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
150 std::vector<std::vector<uint>> UUID_leaf_plant;
151 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
153 std::uniform_real_distribution<float> unif_distribution;
157 bool is_dead =
false;
159 float random_draw = context->
randu();
168 std::vector<float> rad_main;
169 rad_main.push_back(0.75f * trunk_radius);
170 rad_main.push_back(0.8f * trunk_radius);
171 rad_main.push_back(1.f * trunk_radius);
172 rad_main.push_back(0.7f * trunk_radius);
173 rad_main.push_back(0.95f * trunk_radius);
174 rad_main.push_back(0.1f * trunk_radius);
175 std::vector<vec3> pos_main;
176 pos_main.push_back(
make_vec3(0., 0., 0.0));
177 pos_main.push_back(
make_vec3(0, 0, 0.2f * trunk_height));
178 pos_main.push_back(
make_vec3(0, 0, 0.22f * trunk_height));
179 pos_main.push_back(
make_vec3(0, 0, 0.6f * trunk_height));
180 pos_main.push_back(
make_vec3(0, 0, 0.96f * trunk_height));
181 pos_main.push_back(
make_vec3(0., 0., trunk_height));
183 for (
uint i = 0; i < rad_main.size(); i++) {
184 pos_main.at(i) = pos_main.at(i) + origin;
191 if (enable_element_labels) {
201 float diff = cordon_height - trunk_height;
203 float cost = cosf(canopy_rotation);
204 float sint = sinf(canopy_rotation);
206 int Ncord = 2 * wood_subdivisions;
210 std::vector<float> rad_cordw;
211 rad_cordw.push_back(cordon_radius);
212 std::vector<vec3> pos_cordw;
213 pos_cordw.push_back(
make_vec3(0.01f * cordon_length * cost, 0.01f * cordon_length * sint, 0.95 * trunk_height));
217 for (
int i = 1; i < Ncord; i++) {
218 float frac = float(i) / float(Ncord - 1);
219 vec3 n =
spline_interp3(frac, pos_cordw.front(), n_start,
make_vec3(cordon_length * cost, cordon_length * sint, trunk_height + diff), n_end);
220 pos_cordw.push_back(n);
221 rad_cordw.push_back(cordon_radius * (1.f - 0.6f * frac));
224 std::vector<vec3> tmp;
225 tmp.resize(pos_cordw.size());
226 for (
uint i = 0; i < pos_cordw.size(); i++) {
227 tmp.at(i) = pos_cordw.at(i) + origin;
234 std::vector<float> rad_corde;
235 rad_corde.push_back(cordon_radius);
236 std::vector<vec3> pos_corde;
237 pos_corde.push_back(
make_vec3(-0.01f * cordon_length * cost, -0.01f * cordon_length * sint, 0.95f * trunk_height));
239 n_end =
make_vec3(-0.5f * cordon_height, 0, 0);
241 for (
int i = 1; i < Ncord; i++) {
242 float frac = float(i) / float(Ncord - 1);
243 vec3 n =
spline_interp3(frac, pos_corde.front(), n_start,
make_vec3(-cordon_length * cost, -cordon_length * sint, trunk_height + diff), n_end);
244 pos_corde.push_back(n);
245 rad_corde.push_back(cordon_radius * (1.f - 0.6f * frac));
248 tmp.resize(pos_corde.size());
249 for (
uint i = 0; i < pos_corde.size(); i++) {
250 tmp.at(i) = pos_corde.at(i) + origin;
255 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
257 if (enable_element_labels) {
271 float height = cordon_height + shoot_length;
274 for (
uint c = 0; c < 2; c++) {
276 std::vector<float> rad_cord;
277 std::vector<vec3> pos_cord;
280 pos_cord = pos_cordw;
281 rad_cord = rad_cordw;
284 pos_cord = pos_corde;
285 rad_cord = rad_corde;
289 float dx = fabs(pos_cord.back().y - pos_cord.at(0).y) / (float(shoots_per_cordon));
292 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
295 float frac_shoot = float(j) / float(shoots_per_cordon);
299 std::vector<float> rad_pshoot;
300 std::vector<vec3> pos_pshoot;
303 rad_pshoot.push_back(shoot_radius);
304 pos_pshoot.push_back(cane_base);
307 float phirot = (0.5f - unif_distribution(generator)) * 0.5f *
PI_F;
309 if (unif_distribution(generator) < 0.5) {
320 uint Nz = 2 * wood_subdivisions;
321 float dz = ((1 +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
323 float total_cordons_length = 2 * cordon_length;
330 float zfrac_mid = (cane_mid.
z - cane_base.
z) / (cane_end.
z - cane_base.
z);
333 for (
uint k = 1; k < Nz; k++) {
335 float zfrac = float(k) / float(Nz - 1);
338 if (zfrac < zfrac_mid) {
339 n =
spline_interp3(zfrac / zfrac_mid, cane_base, n_start, cane_mid, n_mid);
341 n =
spline_interp3((zfrac - zfrac_mid) / (1 - zfrac_mid), cane_mid, n_mid, cane_end, n_end);
344 pos_pshoot.push_back(n);
346 rad_pshoot.push_back(shoot_radius * (1.f - 0.5f *
float(k) /
float(Nz)));
349 rad_pshoot.back() = 0.0f;
351 std::vector<vec3> tmp;
352 tmp.resize(pos_pshoot.size());
353 for (
uint i = 0; i < pos_pshoot.size(); i++) {
354 tmp.at(i) = pos_pshoot.at(i) + origin;
359 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
360 if (enable_element_labels) {
374 std::vector<std::vector<uint>> UUID_grapes;
375 if (grape_radius > 0 && cluster_radius > 0) {
377 float fgrape = 0.035f + (cluster_height_max - 0.035) * unif_distribution(generator);
380 if (unif_distribution(generator) < 0.5) {
383 vec3 offset(sgn * (0.25f * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (0.1f * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
386 UUID_fruit_plant.push_back(UUID_grapes);
395 if (unif_distribution(generator) < 0.5) {
401 while (lfrac > 0.5 * leaf_width && iter < 100) {
404 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1f * leaf_width);
410 vec3 leaf_offset =
rotatePointAboutLine(
make_vec3(
getVariation(0.1f * lsize, generator),
getVariation(0.75f * lsize, generator), 0),
make_vec3(0, 0, 0), parent_normal, flip *
PI_F +
getVariation(0.25f *
PI_F, generator));
413 if (
int(flip) % 2 == 0) {
419 float Rphi = -canopy_rotation - s * 0.5 *
PI_F * (1.f +
getVariation(0.4f, generator));
422 vec3 position = origin + pos_leaf + leaf_offset;
424 std::vector<uint> UUID_leaf = context->
copyPrimitive(leaf_ptype);
432 UUID_leaf_plant.push_back(UUID_leaf);
434 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
443 UUID_trunk.push_back(UUID_trunk_plant);
444 UUID_branch.push_back(UUID_branch_plant);
445 UUID_leaf.push_back(UUID_leaf_plant);
446 UUID_fruit.push_back(UUID_fruit_plant);
448 return UUID_leaf.size() - 1;
454 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
455 std::vector<std::vector<uint>> UUID_leaf_plant;
456 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
458 std::uniform_real_distribution<float> unif_distribution;
462 bool is_dead =
false;
464 float random_draw = context->
randu();
473 std::vector<float> rad_main;
474 rad_main.push_back(0.75f * trunk_radius);
475 rad_main.push_back(0.8f * trunk_radius);
476 rad_main.push_back(1.f * trunk_radius);
477 rad_main.push_back(0.7f * trunk_radius);
478 rad_main.push_back(0.95f * trunk_radius);
479 rad_main.push_back(0.1f * trunk_radius);
480 std::vector<vec3> pos_main;
481 pos_main.push_back(
make_vec3(0., 0., 0.0));
482 pos_main.push_back(
make_vec3(0, 0, 0.2f * trunk_height));
483 pos_main.push_back(
make_vec3(0, 0, 0.22f * trunk_height));
484 pos_main.push_back(
make_vec3(0, 0, 0.6f * trunk_height));
485 pos_main.push_back(
make_vec3(0, 0, 0.96f * trunk_height));
486 pos_main.push_back(
make_vec3(0., 0., trunk_height));
488 for (
uint i = 0; i < rad_main.size(); i++) {
489 pos_main.at(i) = pos_main.at(i) + origin;
503 float diff = cordon_height - trunk_height;
505 float cost = cosf(canopy_rotation + 0.5f *
PI_F);
506 float sint = sinf(canopy_rotation + 0.5f *
PI_F);
508 std::vector<float> rad_crown;
509 rad_crown.push_back(0.6f * trunk_radius);
510 rad_crown.push_back(0.55f * trunk_radius);
511 rad_crown.push_back(0.5f * trunk_radius);
512 rad_crown.push_back(0.45f * trunk_radius);
513 rad_crown.push_back(0.4f * trunk_radius);
515 std::vector<vec3> pos_crownw;
516 pos_crownw.push_back(
make_vec3(0., 0., 0.95f * trunk_height));
517 pos_crownw.push_back(
make_vec3(0.05f * 0.5f * cordon_spacing * cost, 0.05f * 0.5f * cordon_spacing * sint, trunk_height));
518 pos_crownw.push_back(
make_vec3(0.25f * 0.5f * cordon_spacing * cost, 0.25f * 0.5f * cordon_spacing * sint, trunk_height + 0.1f * diff));
519 pos_crownw.push_back(
make_vec3(0.45f * 0.5f * cordon_spacing * cost, 0.45f * 0.5f * cordon_spacing * sint, trunk_height + 0.65f * diff));
520 pos_crownw.push_back(
make_vec3(0.75f * 0.5f * cordon_spacing * cost, 0.75f * 0.5f * cordon_spacing * sint, cordon_height));
522 for (
uint i = 0; i < rad_crown.size(); i++) {
523 pos_crownw.at(i) = pos_crownw.at(i) + origin;
528 UUID_trunk_plant.insert(UUID_trunk_plant.end(), U.begin(), U.end());
530 std::vector<vec3> pos_crowne;
531 pos_crowne.push_back(
make_vec3(0., 0., 0.95f * trunk_height));
532 pos_crowne.push_back(
make_vec3(-0.05f * 0.5f * cordon_spacing * cost, -0.05f * 0.5f * cordon_spacing * sint, trunk_height));
533 pos_crowne.push_back(
make_vec3(-0.25f * 0.5f * cordon_spacing * cost, -0.25f * 0.5f * cordon_spacing * sint, trunk_height + 0.1f * diff));
534 pos_crowne.push_back(
make_vec3(-0.45f * 0.5f * cordon_spacing * cost, -0.45f * 0.5f * cordon_spacing * sint, trunk_height + 0.65f * diff));
535 pos_crowne.push_back(
make_vec3(-0.75f * 0.5f * cordon_spacing * cost, -0.75f * 0.5f * cordon_spacing * sint, cordon_height));
537 for (
uint i = 0; i < rad_crown.size(); i++) {
538 pos_crowne.at(i) = pos_crowne.at(i) + origin;
543 UUID_trunk_plant.insert(UUID_trunk_plant.end(), U.begin(), U.end());
549 std::vector<float> rad_cord;
550 rad_cord.push_back(cordon_radius);
551 rad_cord.push_back(0.95f * cordon_radius);
552 rad_cord.push_back(0.9f * cordon_radius);
553 rad_cord.push_back(0.9f * cordon_radius);
554 rad_cord.push_back(0.9f * cordon_radius);
555 rad_cord.push_back(0.6f * cordon_radius);
556 rad_cord.push_back(0.2f * cordon_radius);
559 std::vector<vec3> pos_cordnw;
560 pos_cordnw.push_back(
make_vec3(0.7f * 0.5f * cordon_spacing * cost, 0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
561 pos_cordnw.push_back(
make_vec3(0.85f * 0.5f * cordon_spacing * cost + 0.025f * sint, 0.85f * 0.5f * cordon_spacing * sint + 0.025f * cost, cordon_height));
562 pos_cordnw.push_back(
make_vec3(0.95f * 0.5f * cordon_spacing * cost + 0.075f * sint, 0.95f * 0.5f * cordon_spacing * sint + 0.075f * cost, cordon_height));
563 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + 0.12f * sint, 0.5f * cordon_spacing * sint + 0.12f * cost, cordon_height));
564 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + 0.4f * cordon_length * sint, 0.5f * cordon_spacing * sint + 0.4f * cordon_length * cost, 0.94f * cordon_height));
565 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + 0.8f * cordon_length * sint, 0.5f * cordon_spacing * sint + 0.8f * cordon_length * cost, 0.97f * cordon_height));
566 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + cordon_length * sint, 0.5f * cordon_spacing * sint + cordon_length * cost, cordon_height));
568 std::vector<vec3> tmp;
569 tmp.resize(pos_cordnw.size());
570 for (
uint i = 0; i < pos_cordnw.size(); i++) {
571 tmp.at(i) = pos_cordnw.at(i) + origin;
577 std::vector<vec3> pos_cordsw;
578 pos_cordsw.push_back(
make_vec3(0.7f * 0.5f * cordon_spacing * cost, 0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
579 pos_cordsw.push_back(
make_vec3(0.85f * 0.5f * cordon_spacing * cost - 0.025f * sint, 0.85f * 0.5f * cordon_spacing * sint - 0.025f * cost, cordon_height));
580 pos_cordsw.push_back(
make_vec3(0.95f * 0.5f * cordon_spacing * cost - 0.075f * sint, 0.95f * 0.5f * cordon_spacing * sint - 0.075f * cost, cordon_height));
581 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - 0.12f * sint, 0.5f * cordon_spacing * sint - 0.12f * cost, cordon_height));
582 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - 0.4f * cordon_length * sint, 0.5f * cordon_spacing * sint - 0.4f * cordon_length * cost, 0.94f * cordon_height));
583 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - 0.8f * cordon_length * sint, 0.5f * cordon_spacing * sint - 0.8f * cordon_length * cost, 0.97f * cordon_height));
584 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - cordon_length * sint, 0.5f * cordon_spacing * sint - cordon_length * cost, cordon_height));
586 tmp.resize(pos_cordsw.size());
587 for (
uint i = 0; i < pos_cordsw.size(); i++) {
588 tmp.at(i) = pos_cordsw.at(i) + origin;
593 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
596 std::vector<vec3> pos_cordne;
597 pos_cordne.push_back(
make_vec3(-0.7f * 0.5f * cordon_spacing * cost, -0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
598 pos_cordne.push_back(
make_vec3(-0.85f * 0.5f * cordon_spacing * cost + 0.025f * sint, -0.85f * 0.5f * cordon_spacing * sint + 0.025f * cost, cordon_height));
599 pos_cordne.push_back(
make_vec3(-0.95f * 0.5f * cordon_spacing * cost + 0.075f * sint, -0.95f * 0.5f * cordon_spacing * sint + 0.075f * cost, cordon_height));
600 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + 0.12f * sint, -0.5f * cordon_spacing * sint + 0.12f * cost, cordon_height));
601 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + 0.4f * cordon_length * sint, -0.5f * cordon_spacing * sint + 0.4f * cordon_length * cost, 0.94f * cordon_height));
602 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + 0.8f * cordon_length * sint, -0.5f * cordon_spacing * sint + 0.8f * cordon_length * cost, 0.97f * cordon_height));
603 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + cordon_length * sint, -0.5f * cordon_spacing * sint + cordon_length * cost, cordon_height));
605 tmp.resize(pos_cordne.size());
606 for (
uint i = 0; i < pos_cordne.size(); i++) {
607 tmp.at(i) = pos_cordne.at(i) + origin;
612 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
614 std::vector<vec3> pos_cordse;
615 pos_cordse.push_back(
make_vec3(-0.7f * 0.5f * cordon_spacing * cost, -0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
616 pos_cordse.push_back(
make_vec3(-0.85f * 0.5f * cordon_spacing * cost - 0.025f * sint, -0.85f * 0.5f * cordon_spacing * sint - 0.025f * cost, cordon_height));
617 pos_cordse.push_back(
make_vec3(-0.95f * 0.5f * cordon_spacing * cost - 0.075f * sint, -0.95f * 0.5f * cordon_spacing * sint - 0.075f * cost, cordon_height));
618 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - 0.12f * sint, -0.5f * cordon_spacing * sint - 0.12f * cost, cordon_height));
619 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - 0.4f * cordon_length * sint, -0.5f * cordon_spacing * sint - 0.4f * cordon_length * cost, 0.94f * cordon_height));
620 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - 0.8f * cordon_length * sint, -0.5f * cordon_spacing * sint - 0.8f * cordon_length * cost, 0.97f * cordon_height));
621 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - cordon_length * sint, -0.5f * cordon_spacing * sint - cordon_length * cost, cordon_height));
623 tmp.resize(pos_cordse.size());
624 for (
uint i = 0; i < pos_cordse.size(); i++) {
625 tmp.at(i) = pos_cordse.at(i) + origin;
630 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
642 float height = cordon_height + shoot_length;
644 for (
uint d = 0; d < 2; d++) {
645 for (
uint c = 0; c < 2; c++) {
647 std::vector<vec3> pos_cord;
651 pos_cord = pos_cordsw;
653 pos_cord = pos_cordnw;
658 pos_cord = pos_cordse;
660 pos_cord = pos_cordne;
665 float dx = fabs(pos_cord.back().y - pos_cord.at(0).y) / (float(shoots_per_cordon));
667 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
669 float frac_shoot = float(j) / float(shoots_per_cordon);
673 std::vector<float> rad_pshoot;
674 std::vector<vec3> pos_pshoot;
677 rad_pshoot.push_back(shoot_radius);
678 pos_pshoot.push_back(cane_base);
682 float phirot = 0.5f *
PI_F * (1 + (-0.5f + unif_distribution(generator)) * 1.0) + canopy_rotation;
683 if (unif_distribution(generator) < 0.5) {
696 theta0 = 0.5f *
PI_F * unif_distribution(generator);
698 theta0 = shoot_angle_base * (1.f + (-0.5 + unif_distribution(generator)) * 0.6);
700 float theta_end = shoot_angle_tip * (1.f + (-0.5 + unif_distribution(generator)) * 0.6);
702 uint Nz = 2 * wood_subdivisions;
703 float dz = ((1 +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
704 for (
uint k = 1; k < Nz; k++) {
710 rad_pshoot.push_back(shoot_radius);
713 rad_pshoot.back() = 0.0f;
715 std::vector<vec3> tmp;
716 tmp.resize(pos_pshoot.size());
717 for (
uint i = 0; i < pos_pshoot.size(); i++) {
718 tmp.at(i) = pos_pshoot.at(i) + origin;
723 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
735 std::vector<std::vector<uint>> UUID_grapes;
736 if (grape_radius > 0 && cluster_radius > 0) {
738 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
741 if (unif_distribution(generator) < 0.5) {
744 vec3 offset(sgn * (2.2 * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2 * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
748 UUID_fruit_plant.push_back(UUID_grapes);
757 if (unif_distribution(generator) < 0.5) {
763 while (lfrac > 0.5 * leaf_width && iter < 100) {
766 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
775 if (
int(flip) % 2 == 0) {
781 float Rphi = -canopy_rotation - s * 0.5f *
PI_F * (1.f +
getVariation(0.4f, generator));
784 vec3 position = origin + pos_leaf + leaf_offset;
794 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
804 UUID_trunk.push_back(UUID_trunk_plant);
805 UUID_branch.push_back(UUID_branch_plant);
806 UUID_leaf.push_back(UUID_leaf_plant);
807 UUID_fruit.push_back(UUID_fruit_plant);
809 return UUID_leaf.size() - 1;
814 float mean_shoot_angle = 0.1 *
PI_F;
817 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
818 std::vector<std::vector<uint>> UUID_leaf_plant;
819 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
821 std::uniform_real_distribution<float> unif_distribution;
825 float cost = cosf(canopy_rotation);
826 float sint = sinf(canopy_rotation);
828 bool is_dead =
false;
830 float random_draw = context->
randu();
841 std::vector<float> rad_main;
842 rad_main.push_back(0.75 * trunk_radius);
843 rad_main.push_back(0.8f * trunk_radius);
844 rad_main.push_back(1.f * trunk_radius);
845 rad_main.push_back(0.7f * trunk_radius);
846 rad_main.push_back(0.95f * trunk_radius);
847 rad_main.push_back(0.1 * trunk_radius);
848 std::vector<vec3> pos_main;
849 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.0f));
850 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.2f * trunk_height));
851 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.22f * trunk_height));
852 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.6f * trunk_height));
853 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.96f * trunk_height));
854 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, trunk_height));
856 for (
uint i = 0; i < rad_main.size(); i++) {
857 pos_main.at(i) = pos_main.at(i) + origin;
870 float total_cordons_length = 2 * cordon_length;
872 float diff = cordon_height - trunk_height;
875 std::vector<float> rad_cord;
876 rad_cord.push_back(cordon_radius);
877 rad_cord.push_back(0.95 * cordon_radius);
878 rad_cord.push_back(0.9f * cordon_radius);
879 rad_cord.push_back(0.85f * cordon_radius);
880 rad_cord.push_back(0.8 * cordon_radius);
881 rad_cord.push_back(0.6 * cordon_radius);
882 rad_cord.push_back(0.2f * cordon_radius);
883 std::vector<vec3> pos_cord;
884 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.01f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.01f * total_cordons_length) * sint, 0.95f * trunk_height));
885 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.05f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.05f * total_cordons_length) * sint, trunk_height + 0.1f * diff));
886 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.15f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.15f * total_cordons_length) * sint, trunk_height + 0.65f * diff));
887 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.45f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.45f * total_cordons_length) * sint, trunk_height + 0.95f * diff));
888 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.6f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.6f * total_cordons_length) * sint, trunk_height + 1.05f * diff));
889 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 0.85f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 0.85f * total_cordons_length) * sint, trunk_height + diff));
890 pos_cord.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius + 1.0f * total_cordons_length) * cost, (-cordon_length + 0.5f * trunk_radius + 1.0f * total_cordons_length) * sint, trunk_height + diff));
892 std::vector<vec3> tmp;
893 tmp.resize(pos_cord.size());
894 for (
uint i = 0; i < pos_cord.size(); i++) {
895 tmp.at(i) = pos_cord.at(i) + origin;
909 float height = cordon_height + shoot_length;
911 float dx = fabs(pos_cord.back().y - pos_cord.at(0).y) / (float(shoots_per_cordon));
913 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
915 float frac_shoot = float(j) / float(shoots_per_cordon);
919 std::vector<float> rad_pshoot;
920 std::vector<vec3> pos_pshoot;
923 rad_pshoot.push_back(shoot_radius);
924 pos_pshoot.push_back(cane_base);
927 float phirot = (0.5f - unif_distribution(generator)) * 0.5 *
PI_F;
929 if (unif_distribution(generator) < 0.5) {
933 float theta0 = (0.3f - unif_distribution(generator)) * 0.6;
934 float theta_end = (0.1f - unif_distribution(generator)) * 0.2;
936 uint Nz = 2 * wood_subdivisions;
937 float dz = ((1 +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
938 for (
uint k = 1; k < Nz; k++) {
944 rad_pshoot.push_back(shoot_radius);
947 rad_pshoot.back() = 0.0f;
949 std::vector<vec3> tmp;
950 tmp.resize(pos_pshoot.size());
951 for (
uint i = 0; i < pos_pshoot.size(); i++) {
952 tmp.at(i) = pos_pshoot.at(i) + origin;
957 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
969 std::vector<std::vector<uint>> UUID_grapes;
970 if (grape_radius > 0 && cluster_radius > 0) {
972 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
975 if (unif_distribution(generator) < 0.5) {
978 vec3 offset(sgn * (2.2f * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2 * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
981 UUID_fruit_plant.push_back(UUID_grapes);
990 if (unif_distribution(generator) < 0.5) {
996 while (lfrac > 0.5 * leaf_width && iter < 100) {
999 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
1008 if (
int(flip) % 2 == 0) {
1014 float Rphi = -canopy_rotation - s * 0.5f *
PI_F * (1.f +
getVariation(0.4f, generator));
1017 vec3 position = origin + pos_leaf - leaf_offset;
1027 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
1035 UUID_trunk.push_back(UUID_trunk_plant);
1036 UUID_branch.push_back(UUID_branch_plant);
1037 UUID_leaf.push_back(UUID_leaf_plant);
1038 UUID_fruit.push_back(UUID_fruit_plant);
1040 return UUID_leaf.size() - 1;
1046 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
1047 std::vector<std::vector<uint>> UUID_leaf_plant;
1048 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
1050 std::uniform_real_distribution<float> unif_distribution;
1054 float cost = cosf(canopy_rotation);
1055 float sint = sinf(canopy_rotation);
1057 bool is_dead =
false;
1059 float random_draw = context->
randu();
1068 std::vector<float> rad_main;
1069 rad_main.push_back(0.75 * trunk_radius);
1070 rad_main.push_back(0.8f * trunk_radius);
1071 rad_main.push_back(1.f * trunk_radius);
1072 rad_main.push_back(0.7f * trunk_radius);
1073 rad_main.push_back(0.95f * trunk_radius);
1074 rad_main.push_back(0.1 * trunk_radius);
1075 std::vector<vec3> pos_main;
1076 pos_main.push_back(
make_vec3(0., 0., 0.0));
1077 pos_main.push_back(
make_vec3(0, 0, 0.2f * trunk_height));
1078 pos_main.push_back(
make_vec3(0, 0, 0.22f * trunk_height));
1079 pos_main.push_back(
make_vec3(0, 0, 0.6f * trunk_height));
1080 pos_main.push_back(
make_vec3(0, 0, 0.96f * trunk_height));
1081 pos_main.push_back(
make_vec3(0., 0., trunk_height));
1083 for (
uint i = 0; i < rad_main.size(); i++) {
1084 pos_main.at(i) = pos_main.at(i) + origin;
1102 for (
uint c = 0; c < 2; c++) {
1104 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
1106 float frac_shoot = float(j) / float(shoots_per_cordon);
1108 float height = (cordon_height + shoot_length) * (1.f + 0.55 * (1 - frac_shoot));
1112 std::vector<float> rad_pshoot;
1113 std::vector<vec3> pos_pshoot;
1116 rad_pshoot.push_back(shoot_radius);
1117 pos_pshoot.push_back(cane_base);
1119 float theta0 = 0.5 *
PI_F * (1.f - float(j - 1) / float(shoots_per_cordon));
1120 float theta_end = (0.1f - unif_distribution(generator)) * 0.2;
1122 uint Nz = 2 * wood_subdivisions;
1123 float dz = ((1.f +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
1124 for (
uint k = 1; k < Nz; k++) {
1126 vec3 n =
rotatePoint(
make_vec3(0, 0, dz), (theta0 + (theta_end - theta0) *
float(k) /
float(Nz - 1)), canopy_rotation +
PI_F *
float(c));
1130 rad_pshoot.push_back(shoot_radius);
1133 rad_pshoot.back() = 0.0f;
1135 std::vector<vec3> tmp;
1136 tmp.resize(pos_pshoot.size());
1137 for (
uint i = 0; i < pos_pshoot.size(); i++) {
1138 tmp.at(i) = pos_pshoot.at(i) + origin;
1143 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
1155 std::vector<std::vector<uint>> UUID_grapes;
1156 if (grape_radius > 0 && cluster_radius > 0) {
1158 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
1161 if (unif_distribution(generator) < 0.5) {
1164 vec3 offset(sgn * (2.2f * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2.f * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
1167 UUID_fruit_plant.push_back(UUID_grapes);
1176 if (unif_distribution(generator) < 0.5) {
1182 while (lfrac > 0.5 * leaf_width && iter < 100) {
1185 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
1194 if (
int(flip) % 2 == 0) {
1200 float Rphi = -canopy_rotation - s * 0.5 *
PI_F * (1.f +
getVariation(0.4f, generator));
1203 vec3 position = origin + pos_leaf - leaf_offset;
1213 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
1222 UUID_trunk.push_back(UUID_trunk_plant);
1223 UUID_branch.push_back(UUID_branch_plant);
1224 UUID_leaf.push_back(UUID_leaf_plant);
1225 UUID_fruit.push_back(UUID_fruit_plant);
1227 return UUID_leaf.size() - 1;