8 std::vector<std::vector<uint>> U;
17 int Nx = params.leaf_subdivisions.x;
18 int Ny = ceil(params.leaf_subdivisions.y * 0.5);
20 float dx = 1.f / float(Nx);
21 float dy = 0.5f / float(Ny);
23 std::vector<uint> UUIDs;
29 for (
int i = 0; i < Nx; i++) {
30 for (
int j = 0; j < Ny; j++) {
32 float x = float(i) * dx;
33 float y = float(j) * dy;
37 z = a0 * x / (e0 + x) - e0 * y * y;
40 z = a0 * (x + dx) / (e0 + x + dx) - e0 * y * y;
41 vec3 v1(x + dx, y, z);
43 z = a0 * (x + dx) / (e0 + x + dx) - e0 * (y + dy) * (y + dy);
44 vec3 v2(x + dx, y + dy, z);
46 z = a0 * x / (e0 + x) - e0 * (y + dy) * (y + dy);
47 vec3 v3(x, y + dy, z);
49 vec2 uv0(x, 0.5f + j * dy);
50 vec2 uv1(x + dx, 0.5f + j * dy);
51 vec2 uv2(x + dx, 0.5f + (j + 1) * dy);
52 vec2 uv3(x, 0.5f + (j + 1) * dy);
54 UUIDs.push_back(context->
addTriangle(v0, v1, v2, params.leaf_texture_file.c_str(), uv0, uv1, uv2));
55 UUIDs.push_back(context->
addTriangle(v0, v2, v3, params.leaf_texture_file.c_str(), uv0, uv2, uv3));
64 uv2 =
make_vec2(x + dx, 0.5f - (j + 1) * dy);
67 UUIDs.push_back(context->
addTriangle(v0, v2, v1, params.leaf_texture_file.c_str(), uv0, uv2, uv1));
68 UUIDs.push_back(context->
addTriangle(v0, v3, v2, params.leaf_texture_file.c_str(), uv0, uv3, uv2));
85 std::vector<vec3> nodes;
88 nodes.push_back(
make_vec3(0.13, 0, 0.02));
89 nodes.push_back(
make_vec3(0.13, 0, 0.05));
91 float Rpetiole = 0.015;
93 std::vector<float> radius{Rpetiole, Rpetiole, Rpetiole * 0.9f, Rpetiole * 0.8f};
94 std::vector<RGBcolor> color{params.shoot_color, params.shoot_color, params.shoot_color, params.shoot_color};
96 std::vector<uint> U = context->
addTube(params.shoot_subdivisions, nodes, radius, color);
100 UUIDs.insert(UUIDs.end(), U.begin(), U.end());
105void beanLeaflet(
const BeanParameters ¶ms,
const helios::vec3 base_position,
const helios::vec3 base_direction,
float length,
float bend_angle,
float parent_radius, std::vector<std::vector<uint>> &leaf_UUIDs, std::vector<uint> &branch_UUIDs,
106 std::vector<std::vector<std::vector<uint>>> &fruit_UUIDs, std::vector<uint> &leaf_prototype, std::minstd_rand0 &rand_generator,
Context *context) {
108 std::vector<vec3> nodes;
109 std::vector<float> radius;
110 std::vector<RGBcolor> color;
112 int node_count = std::ceil(2.f * length * params.shoot_subdivisions) + 1;
114 vec3 dir = base_direction;
119 nodes.push_back(base_position);
120 radius.push_back(0.5f * parent_radius);
121 color.push_back(params.shoot_color);
124 for (
int i = 1; i < node_count; i++) {
126 float vfrac = float(i) / float(node_count - 1);
128 radius.push_back(0.45f * parent_radius * (1.f - 0.3 * vfrac));
132 theta -= bend_angle / float(node_count - 1);
134 nodes.push_back(position);
136 color.push_back(params.shoot_color);
139 std::vector<uint> U = context->
addTube(params.shoot_subdivisions, nodes, radius, color);
143 branch_UUIDs.insert(branch_UUIDs.end(), U.begin(), U.end());
158 leaf_UUIDs.push_back(U);
162 float leaf_downangle = 0.1 *
PI_F;
163 float leaf_bfrac = 0.8;
172 std::vector<uint> U1 = context->
copyPrimitive(leaf_prototype);
186 std::vector<uint> U2 = context->
copyPrimitive(leaf_prototype);
200 leaf_UUIDs.push_back(U1);
201 leaf_UUIDs.push_back(U2);
205 if (params.pod_length > 0 && context->
randu() < 0.66) {
209 fruit_UUIDs.push_back(beanCluster(cluster_position, params, context));
214 std::vector<std::vector<std::vector<uint>>> &fruit_UUIDs, std::vector<uint> &leaf_prototype, std::minstd_rand0 &rand_generator,
Context *context) {
215 std::vector<std::vector<uint>> UUIDs_leaf;
216 std::vector<std::vector<std::vector<uint>>> UUIDs_pod;
218 std::vector<vec3> nodes;
220 nodes.push_back(base_position +
make_vec3(0, 0, 0) * scale);
221 nodes.push_back(base_position +
make_vec3(0, 0, params.stem_length / 2.f) * scale);
222 nodes.push_back(base_position +
make_vec3(0, 0, params.stem_length) * scale);
224 std::vector<float> radius{params.stem_radius * scale, params.stem_radius * scale, params.stem_radius * scale * 0.9f};
225 std::vector<RGBcolor> color{params.shoot_color, params.shoot_color, params.shoot_color};
227 std::vector<uint> UUIDs_stem = context->
addTube(params.shoot_subdivisions, nodes, radius, color);
231 std::vector<uint> U = context->
copyPrimitive(leaf_prototype);
236 context->
scalePrimitive(U,
make_vec3(params.leaf_length, params.leaf_length * 0.9f, params.leaf_length) * 0.7);
245 leaf_UUIDs.push_back(U);
250 context->
scalePrimitive(U,
make_vec3(params.leaf_length, params.leaf_length * 0.9f, params.leaf_length) * 0.7);
259 leaf_UUIDs.push_back(U);
266 beanLeaflet(params, nodes.back(), leaflet_direction, params.leaflet_length, 0.2 *
PI_F, params.stem_radius, UUIDs_leaf, UUIDs_stem, UUIDs_pod, leaf_prototype, rand_generator, context);
270 beanLeaflet(params, nodes.back(), leaflet_direction, params.leaflet_length, 0.2 *
PI_F, params.stem_radius, UUIDs_leaf, UUIDs_stem, UUIDs_pod, leaf_prototype, rand_generator, context);
272 for (
uint i = 0; i < UUIDs_leaf.size(); i++) {
279 leaf_UUIDs.insert(leaf_UUIDs.end(), UUIDs_leaf.begin(), UUIDs_leaf.end());
280 branch_UUIDs.insert(branch_UUIDs.end(), UUIDs_stem.begin(), UUIDs_stem.end());
281 fruit_UUIDs.insert(fruit_UUIDs.end(), UUIDs_pod.begin(), UUIDs_pod.end());
286 std::vector<std::vector<uint>> leaf_UUIDs;
287 std::vector<uint> branch_UUIDs;
288 std::vector<std::vector<std::vector<uint>>> fruit_UUIDs;
290 std::vector<uint> leaf_prototype = leafPrototype(params, context);
292 beanShoot(params, origin,
make_SphericalCoord(0.5 *
PI_F, 0), 1, leaf_UUIDs, branch_UUIDs, fruit_UUIDs, leaf_prototype, generator, context);
294 UUID_leaf.push_back(leaf_UUIDs);
295 UUID_branch.push_back(branch_UUIDs);
296 UUID_fruit.push_back(fruit_UUIDs);
300 return UUID_leaf.size() - 1;