9 int Nx = params.leaf_subdivisions.x;
10 int Ny = ceil(params.leaf_subdivisions.y * 0.5);
12 float dx = 1.f / float(Nx);
13 float dy = 0.5f / float(Ny);
15 std::uniform_real_distribution<float> unif_distribution;
17 std::vector<uint> UUIDs;
19 float fold = 0.1 *
PI_F;
21 for (
int i = 0; i < Nx; i++) {
22 for (
int j = 0; j < Ny; j++) {
29 mag = sqrt(x * x + 2 * y * y);
33 mag = sqrt((x + dx) * (x + dx) + 2 * y * y);
35 vec3 v1(x + dx, y, z);
37 mag = sqrt((x + dx) * (x + dx) + 2 * (y + dy) * (y + dy));
38 z = (y + dy) * sinf(fold);
39 vec3 v2(x + dx, y + dy, z);
41 mag = sqrt(x * x + 2 * (y + dy) * (y + dy));
42 z = (y + dy) * sinf(fold);
43 vec3 v3(x, y + dy, z);
45 vec2 uv0(x, 0.5 + j * dy);
46 vec2 uv1(x + dx, 0.5 + j * dy);
47 vec2 uv2(x + dx, 0.5 + (j + 1) * dy);
48 vec2 uv3(x, 0.5 + (j + 1) * dy);
50 UUIDs.push_back(
context->addTriangle(v0, v1, v2, params.leaf_texture_file.c_str(), uv0, uv1, uv2));
51 UUIDs.push_back(
context->addTriangle(v0, v2, v3, params.leaf_texture_file.c_str(), uv0, uv2, uv3));
60 uv2 =
make_vec2(x + dx, 0.5 - (j + 1) * dy);
63 UUIDs.push_back(
context->addTriangle(v0, v2, v1, params.leaf_texture_file.c_str(), uv0, uv2, uv1));
64 UUIDs.push_back(
context->addTriangle(v0, v3, v2, params.leaf_texture_file.c_str(), uv0, uv3, uv2));
73 std::vector<uint> UUIDs =
context->addSphere(params.fruit_subdivisions,
make_vec3(0, 0, 0), 1, params.fruit_texture_file.c_str());
84 std::vector<vec3> position;
85 std::vector<float> radius;
108 for (
int i = 0; i < Nsegs; i++) {
110 position.push_back(
spline_interp3(
float(i) /
float(Nsegs - 1), p_start, tan_start, p_end, tan_end));
112 radius.push_back(r_start +
float(i) /
float(Nsegs - 1) * (r_end - r_start));
115 radius.front() *= 1.3;
117 ID =
context->addTubeObject(params.wood_subdivisions, position, radius, params.wood_texture_file.c_str());
122void branchRecursion(
const std::vector<vec3> position_parent,
const std::vector<float> radius_parent,
uint level,
uint max_levels,
const std::vector<uint> leaf_prototype,
const std::vector<uint> nut_prototype, std::vector<uint> &UUID_branch_plant,
123 std::vector<std::vector<uint>> &UUID_leaf_plant, std::vector<std::vector<uint>> &UUID_fruit_plant,
const WalnutCanopyParameters params, std::minstd_rand0 generator,
Context *
context) {
125 std::uniform_real_distribution<float> unif_distribution;
127 if (level > max_levels) {
131 for (
int i = 0; i < Nleaves; i++) {
133 float u = 0.3 + 0.7 * float(i) / float(Nleaves - 1);
146 std::vector<uint> UUIDs =
context->copyPrimitive(leaf_prototype);
147 UUID_leaf_plant.push_back(UUIDs);
149 context->scalePrimitive(UUIDs,
make_vec3(params.leaf_length, 0.5 * params.leaf_length, 0.5 * params.leaf_length));
151 context->rotatePrimitive(UUIDs, elevation,
"x");
152 context->rotatePrimitive(UUIDs, downangle,
"y");
153 context->rotatePrimitive(UUIDs, -azimuth,
"z");
155 context->translatePrimitive(UUIDs, r0 + 0.1 * params.leaf_length *
make_vec3(cosf(-azimuth), sinf(-azimuth), -0.5 * sinf(downangle)));
157 UUIDs =
context->copyPrimitive(leaf_prototype);
158 UUID_leaf_plant.push_back(UUIDs);
160 context->scalePrimitive(UUIDs,
make_vec3(params.leaf_length, 0.5 * params.leaf_length, 0.5 * params.leaf_length));
162 context->rotatePrimitive(UUIDs, elevation,
"x");
163 context->rotatePrimitive(UUIDs, downangle,
"y");
164 context->rotatePrimitive(UUIDs, -azimuth +
PI_F,
"z");
166 context->translatePrimitive(UUIDs, r0 - 0.1 * params.leaf_length *
make_vec3(cosf(-azimuth), sinf(-azimuth), -0.5 * sinf(downangle)));
168 if (i == Nleaves - 1) {
170 UUIDs =
context->copyPrimitive(leaf_prototype);
171 UUID_leaf_plant.push_back(UUIDs);
173 context->scalePrimitive(UUIDs,
make_vec3(params.leaf_length, 0.5 * params.leaf_length, 0.5 * params.leaf_length));
177 context->rotatePrimitive(UUIDs, elevation,
"y");
178 context->rotatePrimitive(UUIDs, 0,
"x");
179 context->rotatePrimitive(UUIDs, -azimuth + 0.5 *
PI_F,
"z");
181 context->translatePrimitive(UUIDs, r0 - 0. * params.leaf_length *
make_vec3(sinf(-azimuth), cosf(-azimuth), 0));
186 if (params.fruit_radius > 0) {
188 float Rnut = unif_distribution(generator);
199 std::vector<uint> nut_UUIDs =
context->copyPrimitive(nut_prototype);
200 UUID_fruit_plant.push_back(nut_UUIDs);
202 context->scalePrimitive(nut_UUIDs,
make_vec3(params.fruit_radius, params.fruit_radius, params.fruit_radius));
204 context->translatePrimitive(nut_UUIDs, r0 - params.fruit_radius *
make_vec3(sinf(-azimuth), cosf(-azimuth), -0.65));
208 std::vector<uint> nut_UUIDs =
context->copyPrimitive(nut_prototype);
209 UUID_fruit_plant.push_back(nut_UUIDs);
211 context->scalePrimitive(nut_UUIDs,
make_vec3(params.fruit_radius, params.fruit_radius, params.fruit_radius));
213 context->translatePrimitive(nut_UUIDs, r0 - params.fruit_radius *
make_vec3(2.f * sinf(-azimuth), 2.f * cosf(-azimuth), -0.85));
217 std::vector<uint> nut_UUIDs =
context->copyPrimitive(nut_prototype);
218 UUID_fruit_plant.push_back(nut_UUIDs);
220 context->scalePrimitive(nut_UUIDs,
make_vec3(params.fruit_radius, params.fruit_radius, params.fruit_radius));
222 context->translatePrimitive(nut_UUIDs, r0 - params.fruit_radius *
make_vec3(sinf(-azimuth), cosf(-azimuth), -0.75));
233 L = params.branch_length.x;
235 }
else if (level == 2) {
236 L = params.branch_length.y;
238 }
else if (level == 3) {
239 L = params.branch_length.z;
250 float phi0 = 2 *
PI_F * unif_distribution(generator);
252 for (
int i = 0; i < Nbranch; i++) {
258 float u = fmin(1.f, 0.2 + 0.8 *
float(i + 1) /
float(Nbranch) +
getVariation(0.05f, generator));
281 float L1 = (0.5 + 0.5 * unif_distribution(generator)) * L;
282 float L2 = (0.5 + 0.5 * unif_distribution(generator)) * L;
286 float rbase2 = rbase1 * (0.4 + 0.6 * L2 / L);
287 rbase1 = rbase1 * (0.4 + 0.6 * L1 / L);
294 uint ID1 = addBranch(pbase, 0.5 * L1 * bnorm1, rbase1, pbase + pend1 * L1, L1 *
make_vec3(0, 0, 1.f +
getVariation(1, generator)), 0.15 * rbase1, 8, params, generator,
context);
295 uint ID2 = addBranch(pbase, 0.5 * L2 * bnorm2, rbase2, pbase + pend2 * L2, L2 *
make_vec3(0, 0, 1.f +
getVariation(1, generator)), 0.15 * rbase2, 8, params, generator,
context);
297 std::vector<uint> UUID =
context->getObjectPrimitiveUUIDs(ID1);
298 UUID_branch_plant.insert(UUID_branch_plant.end(), UUID.begin(), UUID.end());
299 UUID =
context->getObjectPrimitiveUUIDs(ID2);
300 UUID_branch_plant.insert(UUID_branch_plant.end(), UUID.begin(), UUID.end());
302 std::vector<vec3> pos_parent =
context->getTubeObjectNodes(ID1);
303 std::vector<float> rad_parent =
context->getTubeObjectNodeRadii(ID1);
305 branchRecursion(pos_parent, rad_parent, level + 1, max_levels, leaf_prototype, nut_prototype, UUID_branch_plant, UUID_leaf_plant, UUID_fruit_plant, params, generator,
context);
307 pos_parent =
context->getTubeObjectNodes(ID2);
308 rad_parent =
context->getTubeObjectNodeRadii(ID2);
310 branchRecursion(pos_parent, rad_parent, level + 1, max_levels, leaf_prototype, nut_prototype, UUID_branch_plant, UUID_leaf_plant, UUID_fruit_plant, params, generator,
context);
318 std::vector<uint> leaf_prototype = leafPrototype(params, generator,
context);
320 std::vector<uint> nut_prototype = nutPrototype(params,
context);
322 std::vector<uint> UUIDs;
323 std::vector<uint> UUID_branch_plant;
324 std::vector<std::vector<uint>> UUID_leaf_plant;
325 std::vector<std::vector<std::vector<uint>>> UUID_fruit_plant;
326 UUID_fruit_plant.resize(1);
328 std::uniform_real_distribution<float> unif_distribution;
332 uint ID_trunk = addBranch(origin,
make_vec3(0, 0, 1), params.trunk_radius, origin +
make_vec3(unif_distribution(generator) * 3 * params.trunk_radius, unif_distribution(generator) * 3 * params.trunk_radius, params.trunk_height),
333 make_vec3(0, 0, 0.5 * params.trunk_height), 0.5 * params.trunk_radius, 8, params, generator,
context);
335 UUID_trunk.push_back(
context->getObjectPrimitiveUUIDs(ID_trunk));
337 std::vector<vec3> pos_trunk =
context->getTubeObjectNodes(ID_trunk);
338 std::vector<float> rad_trunk =
context->getTubeObjectNodeRadii(ID_trunk);
340 branchRecursion(pos_trunk, rad_trunk, 1, 3, leaf_prototype, nut_prototype, UUID_branch_plant, UUID_leaf_plant, UUID_fruit_plant.front(), params, generator,
context);
343 context->deletePrimitive(leaf_prototype);
344 context->deletePrimitive(nut_prototype);
346 UUID_branch.push_back(UUID_branch_plant);
347 UUID_leaf.push_back(UUID_leaf_plant);
348 UUID_fruit.push_back(UUID_fruit_plant);
350 return UUID_leaf.size() - 1;