@@ -213,9 +213,17 @@ requires is_vec<t_vec>
213
213
while (itervert != vertices.end ())
214
214
{
215
215
const t_vec& vec1 = *itervert;
216
- std::advance (itervert, 1 ); if (itervert == vertices.end ()) break ;
216
+
217
+ std::advance (itervert, 1 );
218
+ if (itervert == vertices.end ())
219
+ break ;
220
+
217
221
const t_vec& vec2 = *itervert;
218
- std::advance (itervert, 1 ); if (itervert == vertices.end ()) break ;
222
+
223
+ std::advance (itervert, 1 );
224
+ if (itervert == vertices.end ())
225
+ break ;
226
+
219
227
const t_vec& vec3 = *itervert;
220
228
std::advance (itervert, 1 );
221
229
@@ -261,9 +269,15 @@ requires is_vec<t_vec>
261
269
{
262
270
// uv coords at vertices
263
271
const t_vec& uv1 = *iteruv;
264
- std::advance (iteruv, 1 ); if (iteruv == uvs.end ()) break ;
272
+ std::advance (iteruv, 1 );
273
+ if (iteruv == uvs.end ())
274
+ break ;
275
+
265
276
const t_vec& uv2 = *iteruv;
266
- std::advance (iteruv, 1 ); if (iteruv == uvs.end ()) break ;
277
+ std::advance (iteruv, 1 );
278
+ if (iteruv == uvs.end ())
279
+ break ;
280
+
267
281
const t_vec& uv3 = *iteruv;
268
282
std::advance (iteruv, 1 );
269
283
@@ -308,7 +322,7 @@ subdivide_triangles(const std::tuple<t_cont<t_vec>, t_cont<t_vec>, t_cont<t_vec>
308
322
requires is_vec<t_vec>
309
323
{
310
324
auto tupDiv = tup;
311
- for (std::size_t i= 0 ; i< iters; ++i)
325
+ for (std::size_t i = 0 ; i < iters; ++i)
312
326
tupDiv = subdivide_triangles<t_vec, t_cont>(tupDiv);
313
327
return tupDiv;
314
328
}
@@ -383,7 +397,7 @@ requires is_vec<t_vec>
383
397
*/
384
398
template <class t_mat , class t_vec , template <class ...> class t_cont = std::vector>
385
399
std::tuple<t_cont<t_vec>, t_cont<t_cont<std::size_t >>, t_cont<t_vec>, t_cont<t_cont<t_vec>>>
386
- create_plane (const t_vec& norm , typename t_vec::value_type l0 = 1 ,
400
+ create_plane (const t_vec& normal , typename t_vec::value_type l0 = 1 ,
387
401
std::optional<typename t_vec::value_type> _l1 = std::nullopt)
388
402
requires is_vec<t_vec>
389
403
{
@@ -399,12 +413,12 @@ requires is_vec<t_vec>
399
413
400
414
// rotate vertices according to given normal
401
415
t_vec norm_old = create<t_vec>({ 0 , 0 , -1 });
402
- t_mat rot = rotation<t_mat, t_vec>(norm_old, norm );
416
+ t_mat rot = rotation<t_mat, t_vec>(norm_old, normal );
403
417
for (t_vec& vec : vertices)
404
418
vec = rot * vec;
405
419
406
420
t_cont<t_cont<std::size_t >> faces = { { 0 , 1 , 2 , 3 } };
407
- t_cont<t_vec> normals = { norm };
421
+ t_cont<t_vec> normals = { normal };
408
422
409
423
t_cont<t_cont<t_vec>> uvs =
410
424
{{
@@ -419,7 +433,7 @@ requires is_vec<t_vec>
419
433
420
434
421
435
/* *
422
- * create a patch
436
+ * create a patch, z = f(x, y)
423
437
* @returns [vertices, face vertex indices, face normals, face uvs]
424
438
*/
425
439
template <class t_func , class t_mat , class t_vec ,
@@ -428,57 +442,72 @@ template<class t_func, class t_mat, class t_vec,
428
442
std::tuple<t_cont<t_vec>, t_cont<t_cont<std::size_t >>, t_cont<t_vec>, t_cont<t_cont<t_vec>>>
429
443
create_patch (const t_func& func,
430
444
t_real width = 1 ., t_real height = 1 .,
431
- std::size_t num_points = 16 )
445
+ std::size_t num_points_x = 16 , std::size_t num_points_y = 16 ,
446
+ const t_vec& normal = create<t_vec>({ 0 , 0 , 1 }))
432
447
requires is_vec<t_vec>
433
448
{
449
+ // rotate according to given normal
450
+ t_vec norm_old = create<t_vec>({ 0 , 0 , 1 });
451
+ t_mat rot = rotation<t_mat, t_vec>(norm_old, normal);
452
+
434
453
// create 2d grid in (x, y) for patch
435
454
t_cont<t_vec> vertices;
436
455
t_cont<t_cont<std::size_t >> faces;
437
456
t_cont<t_vec> normals;
438
457
t_cont<t_cont<t_vec>> uvs;
439
458
440
- vertices.reserve (num_points * num_points );
441
- faces.reserve ((num_points - 1 ) * (num_points - 1 ));
442
- normals.reserve ((num_points - 1 ) * (num_points - 1 ));
443
- uvs.reserve ((num_points - 1 ) * (num_points - 1 ));
459
+ vertices.reserve (num_points_x * num_points_y );
460
+ faces.reserve ((num_points_x - 1 ) * (num_points_y - 1 ));
461
+ normals.reserve ((num_points_x - 1 ) * (num_points_y - 1 ));
462
+ uvs.reserve ((num_points_x - 1 ) * (num_points_y - 1 ));
444
463
445
- for (std::size_t j = 0 ; j < num_points ; ++j)
464
+ for (std::size_t j = 0 ; j < num_points_y ; ++j)
446
465
{
447
466
t_real y = -height*0.5 + height *
448
- static_cast <t_real>(j)/static_cast <t_real>(num_points - 1 );
467
+ static_cast <t_real>(j)/static_cast <t_real>(num_points_y - 1 );
468
+
469
+ t_real v0 = static_cast <t_real>(j - 1 ) / static_cast <t_real>(num_points_x - 1 );
470
+ t_real v1 = static_cast <t_real>(j) / static_cast <t_real>(num_points_y - 1 );
449
471
450
- for (std::size_t i = 0 ; i < num_points ; ++i)
472
+ for (std::size_t i = 0 ; i < num_points_x ; ++i)
451
473
{
474
+ // create vertices
452
475
t_real x = -width*0.5 + width *
453
- static_cast <t_real>(i)/static_cast <t_real>(num_points - 1 );
476
+ static_cast <t_real>(i)/static_cast <t_real>(num_points_x - 1 );
454
477
455
478
t_real z = func (x, y);
456
- vertices.emplace_back (m::create<t_vec>({ x, y, z }));
479
+ vertices.emplace_back (rot * m::create<t_vec>({ x, y, z }));
457
480
481
+ // create faces, normals and uv coords
458
482
if (i > 0 && j > 0 )
459
483
{
460
- std::size_t idx_ij = j*num_points + i;
461
- std::size_t idx_im1j = j*num_points + i - 1 ;
462
- std::size_t idx_i1jm1 = (j - 1 )*num_points + i;
463
- std::size_t idx_im1jm1 = (j - 1 )*num_points + i - 1 ;
484
+ // face
485
+ std::size_t idx_ij = j*num_points_x + i;
486
+ std::size_t idx_im1j = j*num_points_x + i - 1 ;
487
+ std::size_t idx_i1jm1 = (j - 1 )*num_points_x + i;
488
+ std::size_t idx_im1jm1 = (j - 1 )*num_points_x + i - 1 ;
464
489
465
490
faces.emplace_back (t_cont<std::size_t >{{
466
491
idx_im1jm1, idx_i1jm1, idx_ij, idx_im1j
467
492
}});
468
493
494
+ // normal
469
495
t_vec n = cross<t_vec>({
470
496
vertices[idx_i1jm1] - vertices[idx_im1jm1],
471
497
vertices[idx_ij] - vertices[idx_im1jm1]
472
498
});
473
499
n /= norm<t_vec>(n);
500
+ normals.emplace_back (rot * n);
474
501
475
- normals.emplace_back (std::move (n));
502
+ // uv
503
+ t_real u0 = static_cast <t_real>(i - 1 ) / static_cast <t_real>(num_points_x - 1 );
504
+ t_real u1 = static_cast <t_real>(i) / static_cast <t_real>(num_points_x - 1 );
476
505
477
506
uvs.emplace_back (t_cont<t_vec>{{
478
- create<t_vec>({ 0 , 0 }),
479
- create<t_vec>({ 1 , 0 }),
480
- create<t_vec>({ 1 , 1 }),
481
- create<t_vec>({ 0 , 1 }),
507
+ create<t_vec>({ u0, v0 }), // face vertex 0
508
+ create<t_vec>({ u1, v0 }), // face vertex 1
509
+ create<t_vec>({ u1, v1 }), // face vertex 2
510
+ create<t_vec>({ u0, v1 }), // face vertex 3
482
511
}});
483
512
}
484
513
}
@@ -641,7 +670,7 @@ requires is_vec<t_vec>
641
670
t_cont<t_vec> vertices;
642
671
t_cont<t_real> vertices_u;
643
672
644
- for (std::size_t pt= 0 ; pt< num_points; ++pt)
673
+ for (std::size_t pt = 0 ; pt < num_points; ++pt)
645
674
{
646
675
const t_real u = t_real (pt)/t_real (num_points);
647
676
const t_real phi = u * t_real (2 )*pi<t_real>;
@@ -662,7 +691,7 @@ requires is_vec<t_vec>
662
691
t_cont<t_vec> normals;
663
692
t_cont<t_cont<t_vec>> uvs;
664
693
665
- for (std::size_t face= 0 ; face< num_points; ++face)
694
+ for (std::size_t face = 0 ; face < num_points; ++face)
666
695
{
667
696
std::size_t idx0 = face*2 + 0 ; // top 1
668
697
std::size_t idx1 = face*2 + 1 ; // bottom 1
0 commit comments