Skip to content

Commit 5fd0fb1

Browse files
committed
feat: add mesh builder to mesh ext
1 parent b6f4462 commit 5fd0fb1

File tree

3 files changed

+181
-2
lines changed

3 files changed

+181
-2
lines changed

docs/version.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ the API is complete. It just means we won't break what currently exists.
8989
* Physics v0.2.0 (pl_physics_ext.h)
9090
* Collision v0.2.0 (pl_collision_ext.h)
9191
* Mesh v0.1.0 (pl_mesh_ext.h)
92+
* Mesh Builder v0.1.0 (pl_mesh_ext.h)
9293
* Shader Variant v0.2.0 (pl_shader_variant_ext.h)
9394

9495
## Unstable Extensions

extensions/pl_mesh_ext.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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(plMeshBuilder));
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
}

extensions/pl_mesh_ext.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Index of this file:
99
// [SECTION] apis
1010
// [SECTION] includes
1111
// [SECTION] forward declarations & basic types
12-
// [SECTION] public api struct
12+
// [SECTION] public api structs
1313
// [SECTION] structs
1414
// [SECTION] enums
1515
*/
@@ -40,6 +40,7 @@ Index of this file:
4040
//-----------------------------------------------------------------------------
4141

4242
#define plMeshI_version {0, 1, 0}
43+
#define plMeshBuilderI_version {0, 1, 0}
4344

4445
//-----------------------------------------------------------------------------
4546
// [SECTION] includes
@@ -52,17 +53,22 @@ Index of this file:
5253
// [SECTION] forward declarations & basic types
5354
//-----------------------------------------------------------------------------
5455

56+
// basic types
57+
typedef struct _plMeshBuilder plMeshBuilder; // opaque
58+
typedef struct _plMeshBuilderOptions plMeshBuilderOptions;
59+
5560
// ecs components
5661
typedef struct _plMeshComponent plMeshComponent;
5762

5863
// enums & flags
5964
typedef int plMeshFormatFlags;
65+
typedef int plMeshBuilderFlags;
6066

6167
// external
6268
typedef struct _plComponentLibrary plComponentLibrary; // pl_ecs_ext.h
6369

6470
//-----------------------------------------------------------------------------
65-
// [SECTION] public api struct
71+
// [SECTION] public api structs
6672
//-----------------------------------------------------------------------------
6773

6874
typedef struct _plMeshI
@@ -87,10 +93,30 @@ typedef struct _plMeshI
8793
plEcsTypeKey (*get_ecs_type_key_mesh)(void);
8894
} plMeshI;
8995

96+
typedef struct _plMeshBuilderI
97+
{
98+
// setup/shutdown
99+
plMeshBuilder* (*create)(plMeshBuilderOptions);
100+
void (*cleanup)(plMeshBuilder*);
101+
102+
// adding
103+
void (*add_triangle)(plMeshBuilder*, plVec3, plVec3, plVec3);
104+
105+
// commit
106+
void (*commit)(plMeshBuilder*, uint32_t* indexBuffer, plVec3* vertexBuffer, uint32_t* indexBufferCountOut, uint32_t* vertexBufferCountOut);
107+
108+
} plMeshBuilderI;
109+
90110
//-----------------------------------------------------------------------------
91111
// [SECTION] structs
92112
//-----------------------------------------------------------------------------
93113

114+
typedef struct _plMeshBuilderOptions
115+
{
116+
plMeshBuilderFlags tFlags;
117+
float fWeldRadius;
118+
} plMeshBuilderOptions;
119+
94120
typedef struct _plMeshComponent
95121
{
96122
uint64_t ulVertexStreamMask;
@@ -132,4 +158,10 @@ enum _plMeshFormatFlags
132158
PL_MESH_FORMAT_FLAG_HAS_WEIGHTS_1 = 1 << 12
133159
};
134160

161+
enum _plMeshBuilderFlags
162+
{
163+
PL_MESH_BUILDER_FLAGS_NONE = 0,
164+
// PL_MESH_BUILDER_FLAGS_DOUBLE_SIDED = 1 << 0,
165+
};
166+
135167
#endif // PL_MESH_EXT_H

0 commit comments

Comments
 (0)