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);
431 UUID_leaf_plant.push_back(UUID_leaf);
433 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
437 if (enable_element_labels) {
447 UUID_trunk.push_back(UUID_trunk_plant);
448 UUID_branch.push_back(UUID_branch_plant);
449 UUID_leaf.push_back(UUID_leaf_plant);
450 UUID_fruit.push_back(UUID_fruit_plant);
452 return UUID_leaf.size() - 1;
458 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
459 std::vector<std::vector<uint>> UUID_leaf_plant;
460 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
462 std::uniform_real_distribution<float> unif_distribution;
466 bool is_dead =
false;
468 float random_draw = context->
randu();
477 std::vector<float> rad_main;
478 rad_main.push_back(0.75f * trunk_radius);
479 rad_main.push_back(0.8f * trunk_radius);
480 rad_main.push_back(1.f * trunk_radius);
481 rad_main.push_back(0.7f * trunk_radius);
482 rad_main.push_back(0.95f * trunk_radius);
483 rad_main.push_back(0.1f * trunk_radius);
484 std::vector<vec3> pos_main;
485 pos_main.push_back(
make_vec3(0., 0., 0.0));
486 pos_main.push_back(
make_vec3(0, 0, 0.2f * trunk_height));
487 pos_main.push_back(
make_vec3(0, 0, 0.22f * trunk_height));
488 pos_main.push_back(
make_vec3(0, 0, 0.6f * trunk_height));
489 pos_main.push_back(
make_vec3(0, 0, 0.96f * trunk_height));
490 pos_main.push_back(
make_vec3(0., 0., trunk_height));
492 for (
uint i = 0; i < rad_main.size(); i++) {
493 pos_main.at(i) = pos_main.at(i) + origin;
507 float diff = cordon_height - trunk_height;
509 float cost = cosf(canopy_rotation + 0.5f *
PI_F);
510 float sint = sinf(canopy_rotation + 0.5f *
PI_F);
512 std::vector<float> rad_crown;
513 rad_crown.push_back(0.6f * trunk_radius);
514 rad_crown.push_back(0.55f * trunk_radius);
515 rad_crown.push_back(0.5f * trunk_radius);
516 rad_crown.push_back(0.45f * trunk_radius);
517 rad_crown.push_back(0.4f * trunk_radius);
519 std::vector<vec3> pos_crownw;
520 pos_crownw.push_back(
make_vec3(0., 0., 0.95f * trunk_height));
521 pos_crownw.push_back(
make_vec3(0.05f * 0.5f * cordon_spacing * cost, 0.05f * 0.5f * cordon_spacing * sint, trunk_height));
522 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));
523 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));
524 pos_crownw.push_back(
make_vec3(0.75f * 0.5f * cordon_spacing * cost, 0.75f * 0.5f * cordon_spacing * sint, cordon_height));
526 for (
uint i = 0; i < rad_crown.size(); i++) {
527 pos_crownw.at(i) = pos_crownw.at(i) + origin;
532 UUID_trunk_plant.insert(UUID_trunk_plant.end(), U.begin(), U.end());
534 std::vector<vec3> pos_crowne;
535 pos_crowne.push_back(
make_vec3(0., 0., 0.95f * trunk_height));
536 pos_crowne.push_back(
make_vec3(-0.05f * 0.5f * cordon_spacing * cost, -0.05f * 0.5f * cordon_spacing * sint, trunk_height));
537 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));
538 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));
539 pos_crowne.push_back(
make_vec3(-0.75f * 0.5f * cordon_spacing * cost, -0.75f * 0.5f * cordon_spacing * sint, cordon_height));
541 for (
uint i = 0; i < rad_crown.size(); i++) {
542 pos_crowne.at(i) = pos_crowne.at(i) + origin;
547 UUID_trunk_plant.insert(UUID_trunk_plant.end(), U.begin(), U.end());
553 std::vector<float> rad_cord;
554 rad_cord.push_back(cordon_radius);
555 rad_cord.push_back(0.95f * cordon_radius);
556 rad_cord.push_back(0.9f * cordon_radius);
557 rad_cord.push_back(0.9f * cordon_radius);
558 rad_cord.push_back(0.9f * cordon_radius);
559 rad_cord.push_back(0.6f * cordon_radius);
560 rad_cord.push_back(0.2f * cordon_radius);
563 std::vector<vec3> pos_cordnw;
564 pos_cordnw.push_back(
make_vec3(0.7f * 0.5f * cordon_spacing * cost, 0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
565 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));
566 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));
567 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + 0.12f * sint, 0.5f * cordon_spacing * sint + 0.12f * cost, cordon_height));
568 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));
569 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));
570 pos_cordnw.push_back(
make_vec3(0.5f * cordon_spacing * cost + cordon_length * sint, 0.5f * cordon_spacing * sint + cordon_length * cost, cordon_height));
572 std::vector<vec3> tmp;
573 tmp.resize(pos_cordnw.size());
574 for (
uint i = 0; i < pos_cordnw.size(); i++) {
575 tmp.at(i) = pos_cordnw.at(i) + origin;
581 std::vector<vec3> pos_cordsw;
582 pos_cordsw.push_back(
make_vec3(0.7f * 0.5f * cordon_spacing * cost, 0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
583 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));
584 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));
585 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - 0.12f * sint, 0.5f * cordon_spacing * sint - 0.12f * cost, cordon_height));
586 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));
587 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));
588 pos_cordsw.push_back(
make_vec3(0.5f * cordon_spacing * cost - cordon_length * sint, 0.5f * cordon_spacing * sint - cordon_length * cost, cordon_height));
590 tmp.resize(pos_cordsw.size());
591 for (
uint i = 0; i < pos_cordsw.size(); i++) {
592 tmp.at(i) = pos_cordsw.at(i) + origin;
597 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
600 std::vector<vec3> pos_cordne;
601 pos_cordne.push_back(
make_vec3(-0.7f * 0.5f * cordon_spacing * cost, -0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
602 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));
603 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));
604 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + 0.12f * sint, -0.5f * cordon_spacing * sint + 0.12f * cost, cordon_height));
605 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));
606 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));
607 pos_cordne.push_back(
make_vec3(-0.5f * cordon_spacing * cost + cordon_length * sint, -0.5f * cordon_spacing * sint + cordon_length * cost, cordon_height));
609 tmp.resize(pos_cordne.size());
610 for (
uint i = 0; i < pos_cordne.size(); i++) {
611 tmp.at(i) = pos_cordne.at(i) + origin;
616 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
618 std::vector<vec3> pos_cordse;
619 pos_cordse.push_back(
make_vec3(-0.7f * 0.5f * cordon_spacing * cost, -0.7f * 0.5f * cordon_spacing * sint, 0.99f * cordon_height));
620 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));
621 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));
622 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - 0.12f * sint, -0.5f * cordon_spacing * sint - 0.12f * cost, cordon_height));
623 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));
624 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));
625 pos_cordse.push_back(
make_vec3(-0.5f * cordon_spacing * cost - cordon_length * sint, -0.5f * cordon_spacing * sint - cordon_length * cost, cordon_height));
627 tmp.resize(pos_cordse.size());
628 for (
uint i = 0; i < pos_cordse.size(); i++) {
629 tmp.at(i) = pos_cordse.at(i) + origin;
634 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
646 float height = cordon_height + shoot_length;
648 for (
uint d = 0; d < 2; d++) {
649 for (
uint c = 0; c < 2; c++) {
651 std::vector<vec3> pos_cord;
655 pos_cord = pos_cordsw;
657 pos_cord = pos_cordnw;
662 pos_cord = pos_cordse;
664 pos_cord = pos_cordne;
669 float dx = fabs(pos_cord.back().y - pos_cord.at(0).y) / (float(shoots_per_cordon));
671 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
673 float frac_shoot = float(j) / float(shoots_per_cordon);
677 std::vector<float> rad_pshoot;
678 std::vector<vec3> pos_pshoot;
681 rad_pshoot.push_back(shoot_radius);
682 pos_pshoot.push_back(cane_base);
686 float phirot = 0.5f *
PI_F * (1 + (-0.5f + unif_distribution(generator)) * 1.0) + canopy_rotation;
687 if (unif_distribution(generator) < 0.5) {
700 theta0 = 0.5f *
PI_F * unif_distribution(generator);
702 theta0 = shoot_angle_base * (1.f + (-0.5 + unif_distribution(generator)) * 0.6);
704 float theta_end = shoot_angle_tip * (1.f + (-0.5 + unif_distribution(generator)) * 0.6);
706 uint Nz = 2 * wood_subdivisions;
707 float dz = ((1 +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
708 for (
uint k = 1; k < Nz; k++) {
714 rad_pshoot.push_back(shoot_radius);
717 rad_pshoot.back() = 0.0f;
719 std::vector<vec3> tmp;
720 tmp.resize(pos_pshoot.size());
721 for (
uint i = 0; i < pos_pshoot.size(); i++) {
722 tmp.at(i) = pos_pshoot.at(i) + origin;
727 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
739 std::vector<std::vector<uint>> UUID_grapes;
740 if (grape_radius > 0 && cluster_radius > 0) {
742 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
745 if (unif_distribution(generator) < 0.5) {
748 vec3 offset(sgn * (2.2 * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2 * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
752 UUID_fruit_plant.push_back(UUID_grapes);
761 if (unif_distribution(generator) < 0.5) {
767 while (lfrac > 0.5 * leaf_width && iter < 100) {
770 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
779 if (
int(flip) % 2 == 0) {
785 float Rphi = -canopy_rotation - s * 0.5f *
PI_F * (1.f +
getVariation(0.4f, generator));
788 vec3 position = origin + pos_leaf + leaf_offset;
798 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
808 UUID_trunk.push_back(UUID_trunk_plant);
809 UUID_branch.push_back(UUID_branch_plant);
810 UUID_leaf.push_back(UUID_leaf_plant);
811 UUID_fruit.push_back(UUID_fruit_plant);
813 return UUID_leaf.size() - 1;
818 float mean_shoot_angle = 0.1 *
PI_F;
821 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
822 std::vector<std::vector<uint>> UUID_leaf_plant;
823 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
825 std::uniform_real_distribution<float> unif_distribution;
829 float cost = cosf(canopy_rotation);
830 float sint = sinf(canopy_rotation);
832 bool is_dead =
false;
834 float random_draw = context->
randu();
845 std::vector<float> rad_main;
846 rad_main.push_back(0.75 * trunk_radius);
847 rad_main.push_back(0.8f * trunk_radius);
848 rad_main.push_back(1.f * trunk_radius);
849 rad_main.push_back(0.7f * trunk_radius);
850 rad_main.push_back(0.95f * trunk_radius);
851 rad_main.push_back(0.1 * trunk_radius);
852 std::vector<vec3> pos_main;
853 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.0f));
854 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.2f * trunk_height));
855 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.22f * trunk_height));
856 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.6f * trunk_height));
857 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, 0.96f * trunk_height));
858 pos_main.push_back(
make_vec3((-cordon_length + 0.5f * trunk_radius) * cost, (-cordon_length + 0.5f * trunk_radius) * sint, trunk_height));
860 for (
uint i = 0; i < rad_main.size(); i++) {
861 pos_main.at(i) = pos_main.at(i) + origin;
874 float total_cordons_length = 2 * cordon_length;
876 float diff = cordon_height - trunk_height;
879 std::vector<float> rad_cord;
880 rad_cord.push_back(cordon_radius);
881 rad_cord.push_back(0.95 * cordon_radius);
882 rad_cord.push_back(0.9f * cordon_radius);
883 rad_cord.push_back(0.85f * cordon_radius);
884 rad_cord.push_back(0.8 * cordon_radius);
885 rad_cord.push_back(0.6 * cordon_radius);
886 rad_cord.push_back(0.2f * cordon_radius);
887 std::vector<vec3> pos_cord;
888 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));
889 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));
890 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));
891 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));
892 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));
893 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));
894 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));
896 std::vector<vec3> tmp;
897 tmp.resize(pos_cord.size());
898 for (
uint i = 0; i < pos_cord.size(); i++) {
899 tmp.at(i) = pos_cord.at(i) + origin;
913 float height = cordon_height + shoot_length;
915 float dx = fabs(pos_cord.back().y - pos_cord.at(0).y) / (float(shoots_per_cordon));
917 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
919 float frac_shoot = float(j) / float(shoots_per_cordon);
923 std::vector<float> rad_pshoot;
924 std::vector<vec3> pos_pshoot;
927 rad_pshoot.push_back(shoot_radius);
928 pos_pshoot.push_back(cane_base);
931 float phirot = (0.5f - unif_distribution(generator)) * 0.5 *
PI_F;
933 if (unif_distribution(generator) < 0.5) {
937 float theta0 = (0.3f - unif_distribution(generator)) * 0.6;
938 float theta_end = (0.1f - unif_distribution(generator)) * 0.2;
940 uint Nz = 2 * wood_subdivisions;
941 float dz = ((1 +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
942 for (
uint k = 1; k < Nz; k++) {
948 rad_pshoot.push_back(shoot_radius);
951 rad_pshoot.back() = 0.0f;
953 std::vector<vec3> tmp;
954 tmp.resize(pos_pshoot.size());
955 for (
uint i = 0; i < pos_pshoot.size(); i++) {
956 tmp.at(i) = pos_pshoot.at(i) + origin;
961 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
973 std::vector<std::vector<uint>> UUID_grapes;
974 if (grape_radius > 0 && cluster_radius > 0) {
976 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
979 if (unif_distribution(generator) < 0.5) {
982 vec3 offset(sgn * (2.2f * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2 * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
985 UUID_fruit_plant.push_back(UUID_grapes);
994 if (unif_distribution(generator) < 0.5) {
1000 while (lfrac > 0.5 * leaf_width && iter < 100) {
1003 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
1012 if (
int(flip) % 2 == 0) {
1018 float Rphi = -canopy_rotation - s * 0.5f *
PI_F * (1.f +
getVariation(0.4f, generator));
1021 vec3 position = origin + pos_leaf - leaf_offset;
1031 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
1039 UUID_trunk.push_back(UUID_trunk_plant);
1040 UUID_branch.push_back(UUID_branch_plant);
1041 UUID_leaf.push_back(UUID_leaf_plant);
1042 UUID_fruit.push_back(UUID_fruit_plant);
1044 return UUID_leaf.size() - 1;
1050 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
1051 std::vector<std::vector<uint>> UUID_leaf_plant;
1052 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
1054 std::uniform_real_distribution<float> unif_distribution;
1058 float cost = cosf(canopy_rotation);
1059 float sint = sinf(canopy_rotation);
1061 bool is_dead =
false;
1063 float random_draw = context->
randu();
1072 std::vector<float> rad_main;
1073 rad_main.push_back(0.75 * trunk_radius);
1074 rad_main.push_back(0.8f * trunk_radius);
1075 rad_main.push_back(1.f * trunk_radius);
1076 rad_main.push_back(0.7f * trunk_radius);
1077 rad_main.push_back(0.95f * trunk_radius);
1078 rad_main.push_back(0.1 * trunk_radius);
1079 std::vector<vec3> pos_main;
1080 pos_main.push_back(
make_vec3(0., 0., 0.0));
1081 pos_main.push_back(
make_vec3(0, 0, 0.2f * trunk_height));
1082 pos_main.push_back(
make_vec3(0, 0, 0.22f * trunk_height));
1083 pos_main.push_back(
make_vec3(0, 0, 0.6f * trunk_height));
1084 pos_main.push_back(
make_vec3(0, 0, 0.96f * trunk_height));
1085 pos_main.push_back(
make_vec3(0., 0., trunk_height));
1087 for (
uint i = 0; i < rad_main.size(); i++) {
1088 pos_main.at(i) = pos_main.at(i) + origin;
1106 for (
uint c = 0; c < 2; c++) {
1108 for (
int j = 1; j < shoots_per_cordon + 1; j++) {
1110 float frac_shoot = float(j) / float(shoots_per_cordon);
1112 float height = (cordon_height + shoot_length) * (1.f + 0.55 * (1 - frac_shoot));
1116 std::vector<float> rad_pshoot;
1117 std::vector<vec3> pos_pshoot;
1120 rad_pshoot.push_back(shoot_radius);
1121 pos_pshoot.push_back(cane_base);
1123 float theta0 = 0.5 *
PI_F * (1.f - float(j - 1) / float(shoots_per_cordon));
1124 float theta_end = (0.1f - unif_distribution(generator)) * 0.2;
1126 uint Nz = 2 * wood_subdivisions;
1127 float dz = ((1.f +
getVariation(0.1f, generator)) * height - cordon_height) / float(Nz);
1128 for (
uint k = 1; k < Nz; k++) {
1130 vec3 n =
rotatePoint(
make_vec3(0, 0, dz), (theta0 + (theta_end - theta0) *
float(k) /
float(Nz - 1)), canopy_rotation +
PI_F *
float(c));
1134 rad_pshoot.push_back(shoot_radius);
1137 rad_pshoot.back() = 0.0f;
1139 std::vector<vec3> tmp;
1140 tmp.resize(pos_pshoot.size());
1141 for (
uint i = 0; i < pos_pshoot.size(); i++) {
1142 tmp.at(i) = pos_pshoot.at(i) + origin;
1147 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
1159 std::vector<std::vector<uint>> UUID_grapes;
1160 if (grape_radius > 0 && cluster_radius > 0) {
1162 float fgrape = 0.035 + (cluster_height_max - 0.035) * unif_distribution(generator);
1165 if (unif_distribution(generator) < 0.5) {
1168 vec3 offset(sgn * (2.2f * cluster_radius +
getVariation(0.1f, generator)) * sint, sgn * (2.f * cluster_radius +
getVariation(0.1f, generator)) * cost, 0.f);
1171 UUID_fruit_plant.push_back(UUID_grapes);
1180 if (unif_distribution(generator) < 0.5) {
1186 while (lfrac > 0.5 * leaf_width && iter < 100) {
1189 float lsize = fmaxf(leaf_width * (1.f - exp(-5.f * (1 - lfrac))), 0.1 * leaf_width);
1198 if (
int(flip) % 2 == 0) {
1204 float Rphi = -canopy_rotation - s * 0.5 *
PI_F * (1.f +
getVariation(0.4f, generator));
1207 vec3 position = origin + pos_leaf - leaf_offset;
1217 lfrac = lfrac - leaf_spacing_fraction * lsize * (1.f +
getVariation(0.25f, generator));
1226 UUID_trunk.push_back(UUID_trunk_plant);
1227 UUID_branch.push_back(UUID_branch_plant);
1228 UUID_leaf.push_back(UUID_leaf_plant);
1229 UUID_fruit.push_back(UUID_fruit_plant);
1231 return UUID_leaf.size() - 1;