@@ -36,10 +36,18 @@ Index of this file:
3636 #define PL_REALLOC (x , y ) gptMemory->tracked_realloc((x), (y), __FILE__, __LINE__)
3737 #define PL_FREE (x ) gptMemory->tracked_realloc((x), 0, __FILE__, __LINE__)
3838
39+ #ifndef PL_DS_ALLOC
40+ #define PL_DS_ALLOC (x ) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__)
41+ #define PL_DS_ALLOC_INDIRECT (x , FILE , LINE ) gptMemory->tracked_realloc(NULL, (x), FILE, LINE)
42+ #define PL_DS_FREE (x ) gptMemory->tracked_realloc((x), 0, __FILE__, __LINE__)
43+ #endif
44+
3945 static const plLogI * gptLog = NULL ;
4046 static const plEcsI * gptECS = NULL ;
4147#endif
4248
49+ #include "pl_ds.h"
50+
4351//-----------------------------------------------------------------------------
4452// [SECTION] structs
4553//-----------------------------------------------------------------------------
@@ -49,6 +57,20 @@ typedef struct _plMeshContext
4957 plEcsTypeKey tMeshComponentType ;
5058} plMeshContext ;
5159
60+ typedef struct _plMeshBuilderTriangle
61+ {
62+ uint32_t uIndex0 ;
63+ uint32_t uIndex1 ;
64+ uint32_t uIndex2 ;
65+ } plMeshBuilderTriangle ;
66+
67+ typedef struct _plMeshBuilder
68+ {
69+ plMeshBuilderOptions tOptions ;
70+ plVec3 * sbtVertices ;
71+ plMeshBuilderTriangle * sbtTriangles ;
72+ } plMeshBuilder ;
73+
5274//-----------------------------------------------------------------------------
5375// [SECTION] global data
5476//-----------------------------------------------------------------------------
@@ -561,9 +583,122 @@ pl_mesh_register_system(void)
561583 .tSkinComponent = {UINT32_MAX , UINT32_MAX }
562584 };
563585 gptMeshCtx -> tMeshComponentType = gptECS -> register_type (tMeshDesc , & tMeshComponentDefault );
586+ }
587+
588+ plMeshBuilder *
589+ pl_mesh_builder_create (plMeshBuilderOptions tOptions )
590+ {
591+ if (tOptions .fWeldRadius == 0.0f )
592+ tOptions .fWeldRadius = 0.001f ;
593+
594+ plMeshBuilder * ptBuilder = PL_ALLOC (sizeof (ptBuilder ));
595+ memset (ptBuilder , 0 , sizeof (plMeshBuilder ));
596+ ptBuilder -> tOptions = tOptions ;
597+ return ptBuilder ;
598+ }
564599
600+ void
601+ pl_mesh_builder_cleanup (plMeshBuilder * ptBuilder )
602+ {
603+ pl_sb_free (ptBuilder -> sbtTriangles );
604+ pl_sb_free (ptBuilder -> sbtVertices );
605+ PL_FREE (ptBuilder );
565606}
566607
608+ void
609+ pl_mesh_builder_add_triangle (plMeshBuilder * ptBuilder , plVec3 tA , plVec3 tB , plVec3 tC )
610+ {
611+ plMeshBuilderTriangle tTriangle ;
612+ tTriangle .uIndex0 = UINT32_MAX ;
613+ tTriangle .uIndex1 = UINT32_MAX ;
614+ tTriangle .uIndex2 = UINT32_MAX ;
615+
616+ const float fWeldRadiusSqr = ptBuilder -> tOptions .fWeldRadius * ptBuilder -> tOptions .fWeldRadius ;
617+
618+ const uint32_t uVertexCount = pl_sb_size (ptBuilder -> sbtVertices );
619+
620+ for (uint32_t i = 0 ; i < uVertexCount ; i ++ )
621+ {
622+ const plVec3 * ptVertex = & ptBuilder -> sbtVertices [i ];
623+
624+ float fDist = pl_length_sqr_vec3 (pl_sub_vec3 (* ptVertex , tA ));
625+
626+ if (fDist < fWeldRadiusSqr )
627+ {
628+ tTriangle .uIndex0 = i ;
629+ break ;
630+ }
631+ }
632+
633+ for (uint32_t i = 0 ; i < uVertexCount ; i ++ )
634+ {
635+ const plVec3 * ptVertex = & ptBuilder -> sbtVertices [i ];
636+
637+ float fDist = pl_length_sqr_vec3 (pl_sub_vec3 (* ptVertex , tB ));
638+
639+ if (fDist < fWeldRadiusSqr )
640+ {
641+ tTriangle .uIndex1 = i ;
642+ break ;
643+ }
644+ }
645+
646+ for (uint32_t i = 0 ; i < uVertexCount ; i ++ )
647+ {
648+ const plVec3 * ptVertex = & ptBuilder -> sbtVertices [i ];
649+
650+ float fDist = pl_length_sqr_vec3 (pl_sub_vec3 (* ptVertex , tC ));
651+
652+ if (fDist < fWeldRadiusSqr )
653+ {
654+ tTriangle .uIndex2 = i ;
655+ break ;
656+ }
657+ }
658+
659+ if (tTriangle .uIndex0 == UINT32_MAX )
660+ {
661+ tTriangle .uIndex0 = pl_sb_size (ptBuilder -> sbtVertices );
662+ pl_sb_push (ptBuilder -> sbtVertices , tA );
663+ }
664+
665+ if (tTriangle .uIndex1 == UINT32_MAX )
666+ {
667+ tTriangle .uIndex1 = pl_sb_size (ptBuilder -> sbtVertices );
668+ pl_sb_push (ptBuilder -> sbtVertices , tB );
669+ }
670+
671+ if (tTriangle .uIndex2 == UINT32_MAX )
672+ {
673+ tTriangle .uIndex2 = pl_sb_size (ptBuilder -> sbtVertices );
674+ pl_sb_push (ptBuilder -> sbtVertices , tC );
675+ }
676+
677+ pl_sb_push (ptBuilder -> sbtTriangles , tTriangle );
678+ }
679+
680+ void
681+ pl_mesh_builder_commit (plMeshBuilder * ptBuilder , uint32_t * puIndexBuffer , plVec3 * ptVertexBuffer , uint32_t * puIndexBufferCountOut , uint32_t * puVertexBufferCountOut )
682+ {
683+ const uint32_t uVertexCount = pl_sb_size (ptBuilder -> sbtVertices );
684+ const uint32_t uTriangleCount = pl_sb_size (ptBuilder -> sbtTriangles );
685+
686+ if (puVertexBufferCountOut )
687+ * puVertexBufferCountOut = uVertexCount ;
688+
689+ if (puIndexBufferCountOut )
690+ * puIndexBufferCountOut = uTriangleCount * 3 ;
691+
692+ if (puIndexBuffer && ptVertexBuffer )
693+ {
694+ memcpy (puIndexBuffer , ptBuilder -> sbtTriangles , uTriangleCount * 3 * sizeof (uint32_t ));
695+ memcpy (ptVertexBuffer , ptBuilder -> sbtVertices , uVertexCount * sizeof (plVec3 ));
696+ pl_sb_reset (ptBuilder -> sbtTriangles );
697+ pl_sb_reset (ptBuilder -> sbtVertices );
698+ }
699+ }
700+
701+
567702//-----------------------------------------------------------------------------
568703// [SECTION] extension loading
569704//-----------------------------------------------------------------------------
@@ -584,6 +719,14 @@ pl_load_mesh_ext(plApiRegistryI* ptApiRegistry, bool bReload)
584719 };
585720 pl_set_api (ptApiRegistry , plMeshI , & tApi );
586721
722+ const plMeshBuilderI tApi2 = {
723+ .create = pl_mesh_builder_create ,
724+ .cleanup = pl_mesh_builder_cleanup ,
725+ .add_triangle = pl_mesh_builder_add_triangle ,
726+ .commit = pl_mesh_builder_commit ,
727+ };
728+ pl_set_api (ptApiRegistry , plMeshBuilderI , & tApi2 );
729+
587730 gptECS = pl_get_api_latest (ptApiRegistry , plEcsI );
588731 gptMemory = pl_get_api_latest (ptApiRegistry , plMemoryI );
589732 gptLog = pl_get_api_latest (ptApiRegistry , plLogI );
@@ -610,4 +753,7 @@ pl_unload_mesh_ext(plApiRegistryI* ptApiRegistry, bool bReload)
610753
611754 const plMeshI * ptApi = pl_get_api_latest (ptApiRegistry , plMeshI );
612755 ptApiRegistry -> remove_api (ptApi );
756+
757+ const plMeshBuilderI * ptApi2 = pl_get_api_latest (ptApiRegistry , plMeshBuilderI );
758+ ptApiRegistry -> remove_api (ptApi2 );
613759}
0 commit comments