@@ -133,7 +133,7 @@ void CPLYMeshFileLoader::initialize()
133
133
const auto currentBitmask = core::createBitmask ({ attrib });
134
134
inputParams.enabledBindingFlags |= currentBitmask;
135
135
inputParams.enabledAttribFlags |= currentBitmask;
136
- inputParams.bindings [attrib] = { 16 , EVIR_PER_VERTEX };
136
+ inputParams.bindings [attrib] = { asset::getTexelOrBlockBytesize ( static_cast <E_FORMAT>(vertexAttribParamsAllOptions[attrib]. format )) , EVIR_PER_VERTEX };
137
137
inputParams.attributes [attrib] = vertexAttribParamsAllOptions[attrib];
138
138
}
139
139
@@ -353,7 +353,7 @@ asset::SAssetBundle CPLYMeshFileLoader::loadAsset(io::IReadFile* _file, const as
353
353
354
354
mb->setNormalnAttributeIx (3u );
355
355
356
- core::vector<core::vectorSIMDf> attribs [4 ];
356
+ asset::SBufferBinding<asset::ICPUBuffer> attributes [4 ];
357
357
core::vector<uint32_t > indices;
358
358
359
359
bool hasNormals = true ;
@@ -364,14 +364,56 @@ asset::SAssetBundle CPLYMeshFileLoader::loadAsset(io::IReadFile* _file, const as
364
364
// do we want this element type?
365
365
if (ctx.ElementList [i]->Name == " vertex" )
366
366
{
367
+ auto & plyVertexElement = *ctx.ElementList [i];
368
+
369
+ for (auto & vertexProperty : plyVertexElement.Properties )
370
+ {
371
+ const auto propertyName = vertexProperty.Name ;
372
+
373
+ if (propertyName == " x" || propertyName == " y" || propertyName == " z" )
374
+ {
375
+ if (!attributes[ET_POS].buffer )
376
+ {
377
+ attributes[ET_POS].offset = 0u ;
378
+ attributes[ET_POS].buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(asset::getTexelOrBlockBytesize (EF_R32G32B32_SFLOAT) * plyVertexElement.Count );
379
+ }
380
+ }
381
+ else if (propertyName == " nx" || propertyName == " ny" || propertyName == " nz" )
382
+ {
383
+ if (!attributes[ET_NORM].buffer )
384
+ {
385
+ attributes[ET_NORM].offset = 0u ;
386
+ attributes[ET_NORM].buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(asset::getTexelOrBlockBytesize (EF_R32G32B32_SFLOAT) * plyVertexElement.Count );
387
+ }
388
+ }
389
+ else if (propertyName == " u" || propertyName == " s" || propertyName == " v" || propertyName == " t" )
390
+ {
391
+ if (!attributes[ET_UV].buffer )
392
+ {
393
+ attributes[ET_UV].offset = 0u ;
394
+ attributes[ET_UV].buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(asset::getTexelOrBlockBytesize (EF_R32G32_SFLOAT) * plyVertexElement.Count );
395
+ }
396
+ }
397
+ else if (propertyName == " red" || propertyName == " green" || propertyName == " blue" || propertyName == " alpha" )
398
+ {
399
+ if (!attributes[ET_COL].buffer )
400
+ {
401
+ attributes[ET_COL].offset = 0u ;
402
+ attributes[ET_COL].buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(asset::getTexelOrBlockBytesize (EF_R32G32B32A32_SFLOAT) * plyVertexElement.Count );
403
+ }
404
+ }
405
+ }
406
+
367
407
// loop through vertex properties
368
408
for (uint32_t j=0 ; j<ctx.ElementList [i]->Count ; ++j)
369
- hasNormals &= readVertex (ctx, *ctx. ElementList [i], attribs , _params);
409
+ hasNormals &= readVertex (ctx, plyVertexElement, attributes, j , _params);
370
410
}
371
411
else if (ctx.ElementList [i]->Name == " face" )
372
412
{
413
+ const size_t indicesCount = ctx.ElementList [i]->Count ;
414
+
373
415
// read faces
374
- for (uint32_t j=0 ; j < ctx. ElementList [i]-> Count ; ++j)
416
+ for (uint32_t j=0 ; j < indicesCount ; ++j)
375
417
readFace (ctx, *ctx.ElementList [i], indices);
376
418
}
377
419
else
@@ -386,22 +428,22 @@ asset::SAssetBundle CPLYMeshFileLoader::loadAsset(io::IReadFile* _file, const as
386
428
387
429
if (indices.size ())
388
430
{
389
- asset::SBufferBinding<ICPUBuffer> indexBinding = {0 , core::make_smart_refctd_ptr<asset::ICPUBuffer>(indices.size () * sizeof (uint32_t ))};
390
- memcpy (indexBinding.buffer ->getPointer (), indices.data (), indexBinding.buffer ->getSize ());
391
- auto DATA = reinterpret_cast < uint32_t *>(indexBinding. buffer -> getPointer ());
431
+ asset::SBufferBinding<ICPUBuffer> indexBinding = { 0 , core::make_smart_refctd_ptr<asset::ICPUBuffer>(indices.size () * sizeof (uint32_t )) };
432
+ memcpy (indexBinding.buffer ->getPointer (), indices.data (), indexBinding.buffer ->getSize ());
433
+
392
434
mb->setIndexCount (indices.size ());
393
435
mb->setIndexBufferBinding (std::move (indexBinding));
394
- mb->setIndexType (asset::EIT_32BIT);
436
+ mb->setIndexType (asset::EIT_32BIT);
395
437
396
- if (!genVertBuffersForMBuffer (mb.get (), attribs , ctx))
438
+ if (!genVertBuffersForMBuffer (mb.get (), attributes , ctx))
397
439
return {};
398
440
}
399
441
else
400
442
{
401
- mb->setIndexCount (attribs [ET_POS].size ());
443
+ mb->setIndexCount (attributes [ET_POS].buffer -> getSize ());
402
444
mb->setIndexType (EIT_UNKNOWN);
403
445
404
- if (!genVertBuffersForMBuffer (mb.get (), attribs , ctx))
446
+ if (!genVertBuffersForMBuffer (mb.get (), attributes , ctx))
405
447
return {};
406
448
}
407
449
@@ -429,7 +471,7 @@ static void performActionBasedOnOrientationSystem(const asset::IAssetLoader::SAs
429
471
performOnLeftHanded ();
430
472
}
431
473
432
- bool CPLYMeshFileLoader::readVertex (SContext& _ctx, const SPLYElement& Element, core::vector<core::vectorSIMDf> _outAttribs [4 ], const asset::IAssetLoader::SAssetLoadParams& _params)
474
+ bool CPLYMeshFileLoader::readVertex (SContext& _ctx, const SPLYElement& Element, asset::SBufferBinding<asset::ICPUBuffer> outAttributes [4 ], const uint32_t & currentVertexIndex , const asset::IAssetLoader::SAssetLoadParams& _params)
433
475
{
434
476
if (!_ctx.IsBinaryFile )
435
477
getNextLine (_ctx);
@@ -438,94 +480,151 @@ bool CPLYMeshFileLoader::readVertex(SContext& _ctx, const SPLYElement& Element,
438
480
attribs[ET_COL].second .W = 1 .f ;
439
481
attribs[ET_NORM].second .Y = 1 .f ;
440
482
483
+ constexpr auto ET_POS_BYTESIZE = asset::getTexelOrBlockBytesize<EF_R32G32B32_SFLOAT>();
484
+ constexpr auto ET_NORM_BYTESIZE = asset::getTexelOrBlockBytesize<EF_R32G32B32_SFLOAT>();
485
+ constexpr auto ET_UV_BYTESIZE = asset::getTexelOrBlockBytesize<EF_R32G32_SFLOAT>();
486
+ constexpr auto ET_COL_BYTESIZE = asset::getTexelOrBlockBytesize<EF_R32G32B32A32_SFLOAT>();
487
+
441
488
bool result = false ;
442
489
for (uint32_t i = 0 ; i < Element.Properties .size (); ++i)
443
490
{
444
491
E_PLY_PROPERTY_TYPE t = Element.Properties [i].Type ;
445
492
446
493
if (Element.Properties [i].Name == " x" )
447
494
{
448
- attribs[ET_POS].second .X = getFloat (_ctx, t);
495
+ auto & value = attribs[ET_POS].second .X = getFloat (_ctx, t);
449
496
attribs[ET_POS].first = true ;
497
+
498
+ if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES)
499
+ performActionBasedOnOrientationSystem<float >(value, [](float & varToFlip) { varToFlip = -varToFlip; });
500
+
501
+ const size_t propertyOffset = ET_POS_BYTESIZE * currentVertexIndex;
502
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_POS].buffer ->getPointer ()) + propertyOffset;
503
+
504
+ reinterpret_cast <float *>(data)[0 ] = value;
450
505
}
451
506
else if (Element.Properties [i].Name == " y" )
452
507
{
453
- attribs[ET_POS].second .Y = getFloat (_ctx, t);
508
+ auto & value = attribs[ET_POS].second .Y = getFloat (_ctx, t);
454
509
attribs[ET_POS].first = true ;
510
+
511
+ const size_t propertyOffset = ET_POS_BYTESIZE * currentVertexIndex;
512
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_POS].buffer ->getPointer ()) + propertyOffset;
513
+
514
+ reinterpret_cast <float *>(data)[1 ] = value;
455
515
}
456
516
else if (Element.Properties [i].Name == " z" )
457
517
{
458
- attribs[ET_POS].second .Z = getFloat (_ctx, t);
518
+ auto & value = attribs[ET_POS].second .Z = getFloat (_ctx, t);
459
519
attribs[ET_POS].first = true ;
520
+
521
+ const size_t propertyOffset = ET_POS_BYTESIZE * currentVertexIndex;
522
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_POS].buffer ->getPointer ()) + propertyOffset;
523
+
524
+ reinterpret_cast <float *>(data)[2 ] = value;
460
525
}
461
526
else if (Element.Properties [i].Name == " nx" )
462
527
{
463
- attribs[ET_NORM].second .X = getFloat (_ctx, t);
528
+ auto & value = attribs[ET_NORM].second .X = getFloat (_ctx, t);
464
529
attribs[ET_NORM].first = result = true ;
530
+
531
+ if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES)
532
+ performActionBasedOnOrientationSystem<float >(attribs[ET_NORM].second .X , [](float & varToFlip) { varToFlip = -varToFlip; });
533
+
534
+ const size_t propertyOffset = ET_NORM_BYTESIZE * currentVertexIndex;
535
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_NORM].buffer ->getPointer ()) + propertyOffset;
536
+
537
+ reinterpret_cast <float *>(data)[0 ] = value;
465
538
}
466
539
else if (Element.Properties [i].Name == " ny" )
467
540
{
468
- attribs[ET_NORM].second .Y = getFloat (_ctx, t);
541
+ auto & value = attribs[ET_NORM].second .Y = getFloat (_ctx, t);
469
542
attribs[ET_NORM].first = result = true ;
543
+
544
+ const size_t propertyOffset = ET_NORM_BYTESIZE * currentVertexIndex;
545
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_NORM].buffer ->getPointer ()) + propertyOffset;
546
+
547
+ reinterpret_cast <float *>(data)[1 ] = value;
470
548
}
471
549
else if (Element.Properties [i].Name == " nz" )
472
550
{
473
- attribs[ET_NORM].second .Z = getFloat (_ctx, t);
551
+ auto & value = attribs[ET_NORM].second .Z = getFloat (_ctx, t);
474
552
attribs[ET_NORM].first = result = true ;
553
+
554
+ const size_t propertyOffset = ET_NORM_BYTESIZE * currentVertexIndex;
555
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_NORM].buffer ->getPointer ()) + propertyOffset;
556
+
557
+ reinterpret_cast <float *>(data)[2 ] = value;
475
558
}
476
559
// there isn't a single convention for the UV, some softwares like Blender or Assimp use "st" instead of "uv"
477
560
else if (Element.Properties [i].Name == " u" || Element.Properties [i].Name == " s" )
478
561
{
479
- attribs[ET_UV].second .X = getFloat (_ctx, t);
562
+ auto & value = attribs[ET_UV].second .X = getFloat (_ctx, t);
480
563
attribs[ET_UV].first = true ;
564
+
565
+ const size_t propertyOffset = ET_UV_BYTESIZE * currentVertexIndex;
566
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_UV].buffer ->getPointer ()) + propertyOffset;
567
+
568
+ reinterpret_cast <float *>(data)[0 ] = value;
481
569
}
482
570
else if (Element.Properties [i].Name == " v" || Element.Properties [i].Name == " t" )
483
571
{
484
- attribs[ET_UV].second .Y = getFloat (_ctx, t);
572
+ auto & value = attribs[ET_UV].second .Y = getFloat (_ctx, t);
485
573
attribs[ET_UV].first = true ;
574
+
575
+ const size_t propertyOffset = ET_UV_BYTESIZE * currentVertexIndex;
576
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_UV].buffer ->getPointer ()) + propertyOffset;
577
+
578
+ reinterpret_cast <float *>(data)[1 ] = value;
486
579
}
487
580
else if (Element.Properties [i].Name == " red" )
488
581
{
489
582
float value = Element.Properties [i].isFloat () ? getFloat (_ctx, t) : float (getInt (_ctx, t)) / 255 .f ;
490
583
attribs[ET_COL].second .X = value;
491
584
attribs[ET_COL].first = true ;
585
+
586
+ const size_t propertyOffset = ET_COL_BYTESIZE * currentVertexIndex;
587
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_COL].buffer ->getPointer ()) + propertyOffset;
588
+
589
+ reinterpret_cast <float *>(data)[0 ] = value;
492
590
}
493
591
else if (Element.Properties [i].Name == " green" )
494
592
{
495
593
float value = Element.Properties [i].isFloat () ? getFloat (_ctx, t) : float (getInt (_ctx, t)) / 255 .f ;
496
594
attribs[ET_COL].second .Y = value;
497
595
attribs[ET_COL].first = true ;
596
+
597
+ const size_t propertyOffset = ET_COL_BYTESIZE * currentVertexIndex;
598
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_COL].buffer ->getPointer ()) + propertyOffset;
599
+
600
+ reinterpret_cast <float *>(data)[1 ] = value;
498
601
}
499
602
else if (Element.Properties [i].Name == " blue" )
500
603
{
501
604
float value = Element.Properties [i].isFloat () ? getFloat (_ctx, t) : float (getInt (_ctx, t)) / 255 .f ;
502
605
attribs[ET_COL].second .Z = value;
503
606
attribs[ET_COL].first = true ;
607
+
608
+ const size_t propertyOffset = ET_COL_BYTESIZE * currentVertexIndex;
609
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_COL].buffer ->getPointer ()) + propertyOffset;
610
+
611
+ reinterpret_cast <float *>(data)[2 ] = value;
504
612
}
505
613
else if (Element.Properties [i].Name == " alpha" )
506
614
{
507
615
float value = Element.Properties [i].isFloat () ? getFloat (_ctx, t) : float (getInt (_ctx, t)) / 255 .f ;
508
616
attribs[ET_COL].second .W = value;
509
617
attribs[ET_COL].first = true ;
618
+
619
+ const size_t propertyOffset = ET_COL_BYTESIZE * currentVertexIndex;
620
+ uint8_t * data = reinterpret_cast <uint8_t *>(outAttributes[ET_COL].buffer ->getPointer ()) + propertyOffset;
621
+
622
+ reinterpret_cast <float *>(data)[3 ] = value;
510
623
}
511
624
else
512
625
skipProperty (_ctx, Element.Properties [i]);
513
626
}
514
627
515
- for (size_t i = 0u ; i < 4u ; ++i)
516
- if (attribs[i].first )
517
- {
518
- if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES)
519
- {
520
- if (i == ET_POS)
521
- performActionBasedOnOrientationSystem<float >(attribs[ET_POS].second .X , [](float & varToFlip) { varToFlip = -varToFlip; });
522
- else if (i == ET_NORM)
523
- performActionBasedOnOrientationSystem<float >(attribs[ET_NORM].second .X , [](float & varToFlip) { varToFlip = -varToFlip; });
524
- }
525
-
526
- _outAttribs[i].push_back (attribs[i].second );
527
- }
528
-
529
628
return result;
530
629
}
531
630
@@ -688,32 +787,25 @@ void CPLYMeshFileLoader::moveForward(SContext& _ctx, uint32_t bytes)
688
787
689
788
bool CPLYMeshFileLoader::genVertBuffersForMBuffer (
690
789
asset::ICPUMeshBuffer* _mbuf,
691
- const core::vector<core::vectorSIMDf> _attribs [4 ],
790
+ const asset::SBufferBinding<asset::ICPUBuffer> attributes [4 ],
692
791
SContext& context
693
792
) const
694
793
{
695
794
core::vector<uint8_t > availableAttributes;
696
795
for (auto i = 0 ; i < 4 ; ++i)
697
- if (!_attribs [i].empty () )
796
+ if (attributes [i].buffer )
698
797
availableAttributes.push_back (i);
699
798
700
799
{
701
- size_t check = _attribs [0 ].size ();
800
+ size_t check = attributes [0 ].buffer -> getSize ();
702
801
for (size_t i = 1u ; i < 4u ; ++i)
703
802
{
704
- if (_attribs [i].size () != 0u && _attribs [i].size () != check)
803
+ if (attributes [i].buffer && attributes [i].buffer -> getSize () != check)
705
804
return false ;
706
- else if (_attribs [i].size () != 0u )
707
- check = _attribs [i].size ();
805
+ else if (attributes [i].buffer )
806
+ check = attributes [i].buffer -> getSize ();
708
807
}
709
808
}
710
-
711
- auto putAttr = [&_attribs](asset::ICPUMeshBuffer* _buf, size_t _attr)
712
- {
713
- size_t i = 0u ;
714
- for (const core::vectorSIMDf& v : _attribs[_attr])
715
- _buf->setAttribute (v, _attr, i++);
716
- };
717
809
718
810
auto getPipeline = [&]() -> core::smart_refctd_ptr<asset::ICPURenderpassIndependentPipeline>
719
811
{
@@ -756,15 +848,9 @@ bool CPLYMeshFileLoader::genVertBuffersForMBuffer(
756
848
757
849
for (auto index = 0 ; index < 4 ; ++index)
758
850
{
759
- auto attribute = _attribs[index];
760
- if (!attribute.empty ())
761
- {
762
- const auto bufferByteSize = attribute.size () * 16ull ;
763
- auto buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(bufferByteSize);
764
- memcpy (buffer->getPointer (), attribute.data (), bufferByteSize); // TODO refactor input to take SBufferBinding to avoid memcpy
765
-
766
- _mbuf->setVertexBufferBinding ({ 0ul , std::move (buffer) }, index);
767
- }
851
+ auto attribute = attributes[index];
852
+ if (attribute.buffer )
853
+ _mbuf->setVertexBufferBinding (std::move (attribute), index);
768
854
}
769
855
770
856
_mbuf->setPipeline (std::move (mbPipeline));
0 commit comments