1.3.49
 
Loading...
Searching...
No Matches
whitespruce.cpp
1#include "CanopyGenerator.h"
2
3using namespace helios;
4using namespace std;
5
7
8 vector<uint> U;
9 std::vector<uint> UUID_trunk_plant, UUID_branch_plant;
10 std::vector<std::vector<uint>> UUID_leaf_plant;
11
12 std::uniform_real_distribution<float> unif_distribution;
13
14 //------ trunk -------//
15
16 std::vector<float> rad_main;
17 std::vector<vec3> pos_main;
18
19 float dz = params.trunk_height / 10.f;
20 for (int i = 0; i < 10; i++) {
21 rad_main.push_back(params.trunk_radius * (9 - i) / 9.f);
22 pos_main.push_back(make_vec3(0., 0., i * dz));
23 }
24
25 for (uint i = 0; i < rad_main.size(); i++) {
26 pos_main.at(i) = pos_main.at(i) + origin;
27 }
28
29 UUID_trunk_plant = context->addTube(params.wood_subdivisions, pos_main, rad_main, params.wood_texture_file.c_str());
30
31 //---- first order branches -----//
32
33 int Nlevels = floor((params.trunk_height - params.base_height) / params.level_spacing);
34
35 for (int i = 0; i < Nlevels - 1; i++) {
36
37 float vfrac = float(Nlevels - i - 1) / float(Nlevels - 1);
38
39 float rcrown;
40 if (vfrac > 0.3) {
41 rcrown = params.crown_radius;
42 } else {
43 rcrown = fmax(1.f / 0.3 * vfrac * params.crown_radius, 0.2 * params.crown_radius);
44 }
45 // rcrown += getVariation(0.1*rcrown,generator);
46
47 float z = fmin(params.trunk_height, params.base_height + i * params.level_spacing * (1 + getVariation(0.1f * params.level_spacing, generator)));
48
49 int Nbranches = fmax(4, params.branches_per_level * vfrac);
50
51 for (int j = 0; j < Nbranches; j++) {
52
53 float phi = float(j) / float(Nbranches) * 2.f * PI_F * (1 + getVariation(0.1f, generator));
54
55 float theta = -0.15 * PI_F;
56 theta += getVariation(0.2f * fabs(theta), generator);
57
58 std::vector<float> rad_branch;
59 std::vector<vec3> pos_branch;
60
61 z += getVariation(0.5f, generator);
62
63 float r = rcrown + getVariation(0.1f * rcrown, generator);
64
65 pos_branch.push_back(origin + make_vec3(0, 0, z));
66 pos_branch.push_back(origin + make_vec3(r * sinf(phi) * cosf(theta), r * cosf(phi) * cosf(theta), z + r * sinf(theta)));
67
68 // printf("pos_branch = (%f,%f,%f)\n",pos_branch.front().x,pos_branch.front().y,pos_branch.front().z);
69
70 rad_branch.push_back(params.shoot_radius * vfrac);
71 rad_branch.push_back(0.1 * params.shoot_radius * vfrac);
72
73 // printf("rad_branch = %f\n",rad_branch.back());
74
75 U = context->addTube(params.wood_subdivisions, pos_branch, rad_branch, params.wood_texture_file.c_str());
76 UUID_branch_plant.insert(UUID_branch_plant.end(), U.begin(), U.end());
77
78 for (int k = 0; k < 2 * Nbranches; k++) {
79
80 float bfrac = float(k + 1) / float(2 * Nbranches);
81 // bfrac = 4.f/0.8*bfrac/(4*bfrac+1.f);
82
83 int side = k % 2;
84
85 std::vector<float> rad_subbranch;
86 std::vector<vec3> pos_subbranch;
87
88 vec3 base = interpolateTube(pos_branch, bfrac);
89 float rbase = interpolateTube(rad_branch, bfrac);
90
91 pos_subbranch.push_back(base);
92
93 float l = fmax(0.1, 0.6 * rcrown);
94 l += getVariation(0.25f * l, generator);
95
96 float bangle = 0.2 * PI_F;
97 // vec3 bdir = l*make_vec3(sinf(phi)*cosf(theta+bangle),cosf(phi)*cosf(theta+0.5*PI_F),sinf(theta+bangle));
98 // bdir = rotatePointAboutLine( bdir, base, interpolateTube( pos_branch, bfrac-0.01 ), getVariation(PI_F,generator) );
99
100 vec3 bdir = l * make_vec3(sinf(phi + (0.4 + getVariation(0.1f, generator)) * PI_F * (-1 + 2 * side)), cosf(phi - 0.4 * PI_F + 0.8 * PI_F * side), 0);
101
102 pos_subbranch.push_back(base + bdir);
103
104 rad_subbranch.push_back(rbase);
105 rad_subbranch.push_back(0.1 * rbase);
106
107 // UUID_branch = context->addTube(params.wood_subdivisions,pos_subbranch,rad_subbranch, params.wood_texture_file.c_str() );
108 // context->addTube(params.wood_subdivisions,pos_subbranch,rad_subbranch, params.wood_texture_file.c_str() );
109
110 // needles
111 int Nneedles = round(50 * l / (0.4 * params.crown_radius));
112 for (int n = 0; n < Nneedles; n++) {
113
114 float nfrac = float(n + 1) / float(Nneedles);
115 // nfrac = 4.f/0.8*nfrac/(4*nfrac+1.f);
116
117 vec3 nbase = interpolateTube(pos_subbranch, nfrac);
118 vec3 nbase_p = interpolateTube(pos_subbranch, 0.99 * nfrac);
119
120 vec3 norm = nbase - nbase_p;
121 // n.normalize();
122
123 SphericalCoord rotation = cart2sphere(norm);
124
125 UUID_leaf_plant.push_back(context->addTile(make_vec3(0, 0, 0), make_vec2(0.1 * params.needle_length, params.needle_length), make_SphericalCoord(0, 0), params.needle_subdivisions, params.needle_color));
126
127 float downangle = 0.2 * PI_F;
128 context->rotatePrimitive(UUID_leaf_plant.back(), downangle - rotation.elevation, "x");
129 context->translatePrimitive(UUID_leaf_plant.back(), make_vec3(0, -0.55 * params.needle_length, 0));
130 context->rotatePrimitive(UUID_leaf_plant.back(), 0.5 * PI_F - rotation.azimuth, "z");
131 context->rotatePrimitive(UUID_leaf_plant.back(), getVariation(PI_F, generator), norm);
132 context->translatePrimitive(UUID_leaf_plant.back(), nbase);
133 }
134 }
135 }
136 }
137
138 UUID_trunk.push_back(UUID_trunk_plant);
139 UUID_branch.push_back(UUID_branch_plant);
140 UUID_leaf.push_back(UUID_leaf_plant);
141 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
142 UUID_fruit.push_back(UUID_fruit_plant);
143
144 return UUID_leaf.size() - 1;
145}