destruction data for destroy callbacks

main
cosmonaut 2021-09-28 22:03:07 -07:00
parent 47ceb50cd9
commit b96860705d
2 changed files with 89 additions and 0 deletions

View File

@ -318,6 +318,15 @@ typedef struct Silkworm_Context
uint32_t clothDensity;
uint8_t* currentBufferAddress; /* GM doesnt let you pass more than 4 arguments with different types lol */
/* keep track of these so can do callbacks */
Silkworm_Vector2* nodeDestructionData;
uint32_t nodeDestructionDataCount;
uint32_t nodeDestructionDataCapacity;
Silkworm_Vector2* linkDestructionData;
uint32_t linkDestructionDataCount;
uint32_t linkDestructionDataCapacity;
} Silkworm_Context;
static Silkworm_Context *context = NULL;
@ -353,6 +362,14 @@ void Silkworm_Init()
context->xBound = 1000;
context->yBound = 1000;
context->clothDensity = 4;
context->nodeDestructionDataCapacity = 16;
context->nodeDestructionData = malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity);
context->nodeDestructionDataCount = 0;
context->linkDestructionDataCapacity = 16;
context->linkDestructionData = malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity);
context->linkDestructionDataCount = 0;
}
static inline Silkworm_Node* LookupNode(uint64_t nodeId)
@ -394,6 +411,18 @@ void Silkworm_DestroyNode(double nodeId)
void Silkworm_Internal_DestroyLink(Silkworm_Link* link)
{
link->markedForDestroy = true;
if (context->linkDestructionDataCount >= context->linkDestructionDataCapacity)
{
context->linkDestructionDataCapacity *= 2;
context->linkDestructionData = realloc(context->linkDestructionData, sizeof(Silkworm_Vector2) * context->linkDestructionDataCapacity);
}
Silkworm_Vector2 position;
position.x = (link->a->position.x + link->b->position.x) / 2;
position.y = (link->a->position.y + link->b->position.y) / 2;
context->linkDestructionData[context->linkDestructionDataCount] = position;
context->linkDestructionDataCount += 1;
}
void Silkworm_DestroyLink(double linkId)
@ -580,6 +609,9 @@ void Silkworm_Update(double deltaTime)
Silkworm_Link *link;
Silkworm_Node *node;
context->nodeDestructionDataCount = 0;
context->linkDestructionDataCount = 0;
float delta = (float)deltaTime;
for (i = 0; i < CONSTRAINT_ITERATION_COUNT; i += 1)
@ -1449,6 +1481,16 @@ void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
if (squareDistance <= radius * radius)
{
Silkworm_DestroyNode(i);
if (context->nodeDestructionDataCount >= context->nodeDestructionDataCapacity)
{
context->nodeDestructionDataCapacity *= 2;
context->nodeDestructionData = realloc(context->nodeDestructionData, sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity);
}
context->nodeDestructionData[context->nodeDestructionDataCount] = node->position;
context->nodeDestructionDataCount += 1;
}
}
}
@ -1505,6 +1547,44 @@ double Silkworm_DestroyClothInRadius(double x, double y, double radius)
return clothId;
}
double Silkworm_NodeDestructionDataBufferRequiredSize()
{
return context->nodeDestructionDataCount * (double)sizeof(Silkworm_Vector2);
}
double Silkworm_FillNodeDestructionDataBuffer()
{
uint32_t i;
uint8_t* bufferAddress = context->currentBufferAddress;
for (i = 0; i < context->nodeDestructionDataCount; i += 1)
{
memcpy(bufferAddress, &context->nodeDestructionData[i], sizeof(Silkworm_Vector2));
bufferAddress += sizeof(Silkworm_Vector2);
}
return (double)i;
}
double Silkworm_LinkDestructionDataBufferRequiredSize()
{
return context->linkDestructionDataCount * (double)sizeof(Silkworm_Vector2);
}
double Silkworm_FillLinkDestructionDataBuffer()
{
uint32_t i;
uint8_t* bufferAddress = context->currentBufferAddress;
for (i = 0; i < context->linkDestructionDataCount; i += 1)
{
memcpy(bufferAddress, &context->linkDestructionData[i], sizeof(Silkworm_Vector2));
bufferAddress += sizeof(Silkworm_Vector2);
}
return (double)i;
}
void Silkworm_ClearAll()
{
uint32_t i;
@ -1532,6 +1612,9 @@ void Silkworm_Finish()
free(context->linkIndexStack);
free(context->clothIndexStack);
free(context->nodeDestructionData);
free(context->linkDestructionData);
free(context);
context = NULL;
}

View File

@ -90,6 +90,12 @@ SILKWORMAPI void Silkworm_PushNodesInRadius(double x, double y, double radius, d
SILKWORMAPI void Silkworm_DestroyNodesInRadius(double x, double y, double radius);
SILKWORMAPI double Silkworm_DestroyClothInRadius(double x, double y, double radius);
SILKWORMAPI double Silkworm_NodeDestructionDataBufferRequiredSize();
SILKWORMAPI double Silkworm_FillNodeDestructionDataBuffer();
SILKWORMAPI double Silkworm_LinkDestructionDataBufferRequiredSize();
SILKWORMAPI double Silkworm_FillLinkDestructionDataBuffer();
SILKWORMAPI void Silkworm_ClearAll();
SILKWORMAPI void Silkworm_Finish();