diff --git a/src/Silkworm2.c b/src/Silkworm2.c index e0636e3..fb6bc63 100644 --- a/src/Silkworm2.c +++ b/src/Silkworm2.c @@ -89,12 +89,12 @@ typedef struct Silkworm_Node float mass; float friction; float radius; - bool pinned; + uint8_t pinned; float pushFactor; float windFactor; - bool destroyable; + uint8_t destroyable; - bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */ + uint8_t markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */ Silkworm_Link** links; uint32_t linkCount; @@ -110,7 +110,7 @@ struct Silkworm_Link float distance; float tearThreshold; - bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */ + uint8_t markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */ }; typedef enum Silkworm_ClothTriangleOrientation @@ -192,7 +192,7 @@ static inline void NodeTriangleHashTable_Insert( uint32_t i; uint64_t hashcode = NodeTriangleHashTable_GetHashCode(key); NodeTriangleHashArray* arr = &table->buckets[hashcode % NUM_NODE_TRIANGLE_HASH_BUCKETS]; - bool foundKey = false; + uint8_t foundKey = 0; for (i = 0; i < arr->count; i += 1) { @@ -201,7 +201,7 @@ static inline void NodeTriangleHashTable_Insert( arr->elements[i].indexArray = Silkworm_realloc(arr->elements[i].indexArray, sizeof(uint32_t) * (arr->elements[i].indexArrayCount + 1)); arr->elements[i].indexArray[arr->elements[i].indexArrayCount] = index; arr->elements[i].indexArrayCount += 1; - foundKey = true; + foundKey = 1; break; } } @@ -274,7 +274,7 @@ static inline void LinkTriangleHashTable_Insert( uint32_t i; uint64_t hashcode = LinkTriangleHashTable_GetHashCode(key); LinkTriangleHashArray* arr = &table->buckets[hashcode % NUM_LINK_TRIANGLE_HASH_BUCKETS]; - bool foundKey = false; + uint8_t foundKey = 0; for (i = 0; i < arr->count; i += 1) { @@ -283,7 +283,7 @@ static inline void LinkTriangleHashTable_Insert( arr->elements[i].indexArray = Silkworm_realloc(arr->elements[i].indexArray, sizeof(uint32_t) * (arr->elements[i].indexArrayCount + 1)); arr->elements[i].indexArray[arr->elements[i].indexArrayCount] = index; arr->elements[i].indexArrayCount += 1; - foundKey = true; + foundKey = 1; break; } } @@ -363,14 +363,9 @@ typedef struct Silkworm_Context float timeElapsed; - /* 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; + /* keep track of these so we can query */ + uint32_t destroyedNodeCount; + uint32_t destroyedLinkCount; Silkworm_Vertex* vertexBuffer; uint32_t vertexCapacity; @@ -411,13 +406,8 @@ void Silkworm_Init() context->clothDensity = 4; context->timeElapsed = 0; - context->nodeDestructionDataCapacity = 16; - context->nodeDestructionData = Silkworm_malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity); - context->nodeDestructionDataCount = 0; - - context->linkDestructionDataCapacity = 16; - context->linkDestructionData = Silkworm_malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity); - context->linkDestructionDataCount = 0; + context->destroyedNodeCount = 0; + context->destroyedLinkCount = 0; context->vertexCapacity = 1024; context->vertexBuffer = Silkworm_malloc(sizeof(Silkworm_Vertex) * context->vertexCapacity); @@ -440,40 +430,39 @@ static inline Silkworm_Cloth* LookupCloth(uint64_t clothId) /* we defer actual destruction to Update to avoid issues with NULL */ -void Silkworm_DestroyNode(void* nodePtr) +static void Silkworm_Internal_DestroyNode(void* nodePtr, uint8_t incrementDestroyCount) { uint32_t i; Silkworm_Node* node = (Silkworm_Node*) nodePtr; if (node != NULL) { - node->markedForDestroy = true; + node->markedForDestroy = 1; + + if (incrementDestroyCount) + { + context->destroyedNodeCount += 1; + } for (i = 0; i < node->linkCount; i += 1) { if (node->links[i] != NULL) { - node->links[i]->markedForDestroy = true; + node->links[i]->markedForDestroy = 1; } } } } +void Silkworm_DestroyNode(void* nodePtr) +{ + Silkworm_Internal_DestroyNode(nodePtr, 0); +} + void Silkworm_DestroyLink(Silkworm_Link* link) { - link->markedForDestroy = true; - - if (context->linkDestructionDataCount >= context->linkDestructionDataCapacity) - { - context->linkDestructionDataCapacity *= 2; - context->linkDestructionData = Silkworm_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; + link->markedForDestroy = 1; + context->destroyedLinkCount += 1; } void Silkworm_ClothDestroy(void* clothPtr) @@ -518,7 +507,7 @@ void Silkworm_ClothDestroy(void* clothPtr) if (node != NULL) { - Silkworm_DestroyNode(node); + Silkworm_Internal_DestroyNode(node, 0); } } Silkworm_free(cloth->nodes[i]); @@ -659,8 +648,8 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY) Silkworm_Link *link; Silkworm_Node *node; - context->nodeDestructionDataCount = 0; - context->linkDestructionDataCount = 0; + context->destroyedNodeCount = 0; + context->destroyedLinkCount = 0; // apply wind for (i = 0; i < context->nodeCount; i += 1) @@ -747,7 +736,7 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY) if (Silkworm_fabs(node->position.x) > context->xBound || Silkworm_fabs(node->position.x) > context->yBound) { - Silkworm_DestroyNode(node); + Silkworm_Internal_DestroyNode(node, 0); } } } @@ -792,9 +781,9 @@ void* Silkworm_CreateNode(Silkworm_NodeCreateInfo* nodeCreateInfo) node->radius = (float) nodeCreateInfo->radius; node->pushFactor = (float) nodeCreateInfo->pushFactor; node->windFactor = (float) nodeCreateInfo->windFactor; - node->pinned = false; - node->destroyable = false; - node->markedForDestroy = false; + node->pinned = 0; + node->destroyable = 0; + node->markedForDestroy = 0; node->links = NULL; node->linkCount = 0; @@ -807,7 +796,7 @@ void Silkworm_ClothNodePin(void* clothPtr, uint32_t i, uint32_t j) Silkworm_Node* node = cloth->nodes[i][j]; if (node != NULL) { - node->pinned = true; + node->pinned = 1; } } @@ -817,7 +806,7 @@ void Silkworm_ClothNodeUnpin(void* clothPtr, uint32_t i, uint32_t j) Silkworm_Node* node = cloth->nodes[i][j]; if (node != NULL) { - node->pinned = false; + node->pinned = 0; } } @@ -827,7 +816,7 @@ void Silkworm_ClothNodeDestroy(void* clothPtr, uint32_t i, uint32_t j) Silkworm_Node* node = cloth->nodes[i][j]; if (node != NULL) { - Silkworm_DestroyNode(node); + Silkworm_Internal_DestroyNode(node, 0); } } @@ -860,7 +849,7 @@ void* Silkworm_CreateLink(void* nodeAPtr, void* nodeBPtr, float distance, float link->b = nodeB; link->distance = (float)distance; link->tearThreshold = (float)tearThreshold; - link->markedForDestroy = false; + link->markedForDestroy = 0; link->a->links = Silkworm_realloc(link->a->links, sizeof(Silkworm_Link*) * (link->a->linkCount + 1)); link->a->links[link->a->linkCount] = link; @@ -925,10 +914,10 @@ void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo) { nodeCreateInfo.x = clothCreateInfo->x + i * context->clothDensity; nodeCreateInfo.y = clothCreateInfo->y + j * context->clothDensity; - nodeCreateInfo.destroyable = true; + nodeCreateInfo.destroyable = 1; nodeCreateInfo.friction = clothCreateInfo->friction; nodeCreateInfo.mass = clothCreateInfo->mass; - nodeCreateInfo.pinned = false; + nodeCreateInfo.pinned = 0; nodeCreateInfo.pushFactor = 1; nodeCreateInfo.radius = 1; nodeCreateInfo.windFactor = clothCreateInfo->windFactor; @@ -937,7 +926,7 @@ void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo) cloth->nodes[i][j] = node; - node->destroyable = true; + node->destroyable = 1; node->clothReference.clothId = cloth->id; node->clothReference.horizontalIndex = i; @@ -1202,7 +1191,7 @@ void Silkworm_PinNodesInRadius(float x, float y, float radius) if (squareDistance <= radius * radius) { - node->pinned = true; + node->pinned = 1; } } } @@ -1227,7 +1216,7 @@ void Silkworm_UnpinNodesInRadius(float x, float y, float radius) if (squareDistance <= radius * radius) { - node->pinned = false; + node->pinned = 0; } } } @@ -1252,17 +1241,7 @@ void Silkworm_DestroyNodesInRadius(float x, float y, float radius) if (squareDistance <= radius * radius) { - Silkworm_DestroyNode(node); - - if (context->nodeDestructionDataCount >= context->nodeDestructionDataCapacity) - { - context->nodeDestructionDataCapacity *= 2; - context->nodeDestructionData = Silkworm_realloc(context->nodeDestructionData, sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity); - - } - - context->nodeDestructionData[context->nodeDestructionDataCount] = node->position; - context->nodeDestructionDataCount += 1; + Silkworm_Internal_DestroyNode(node, 1); } } } @@ -1288,22 +1267,22 @@ void Silkworm_DestroyNodesInRectangle(Silkworm_Rectangle* rectangle) node->position.y >= rectangle->y && node->position.y <= rectangle->y + rectangle->h ) { - Silkworm_DestroyNode(node); - - if (context->nodeDestructionDataCount >= context->nodeDestructionDataCapacity) - { - context->nodeDestructionDataCapacity *= 2; - context->nodeDestructionData = Silkworm_realloc(context->nodeDestructionData, sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity); - - } - - context->nodeDestructionData[context->nodeDestructionDataCount] = node->position; - context->nodeDestructionDataCount += 1; + Silkworm_Internal_DestroyNode(node, 1); } } } } +uint32_t Silkworm_DestroyedNodeCount() +{ + return context->destroyedNodeCount; +} + +uint32_t Silkworm_DestroyedLinkCount() +{ + return context->destroyedLinkCount; +} + void* Silkworm_FindClothInRadius(float x, float y, float radius) { /* TODO: spatial hash implementation */ @@ -1365,9 +1344,6 @@ void Silkworm_Finish() Silkworm_free(context->linkIndexStack); Silkworm_free(context->clothIndexStack); - Silkworm_free(context->nodeDestructionData); - Silkworm_free(context->linkDestructionData); - Silkworm_free(context->vertexBuffer); Silkworm_free(context); diff --git a/src/Silkworm2.h b/src/Silkworm2.h index 7cb7587..090d301 100644 --- a/src/Silkworm2.h +++ b/src/Silkworm2.h @@ -27,8 +27,6 @@ #ifndef SILKWORM_H #define SILKWORM_H -#include -#include #include #ifdef _WIN32 @@ -63,10 +61,10 @@ typedef struct Silkworm_NodeCreateInfo float mass; float friction; float radius; - bool pinned; + uint8_t pinned; float pushFactor; float windFactor; - bool destroyable; + uint8_t destroyable; } Silkworm_NodeCreateInfo; typedef struct Silkworm_ClothCreateInfo @@ -126,6 +124,9 @@ SILKWORMAPI void* Silkworm_FindClothInRadius(float x, float y, float radius); SILKWORMAPI void Silkworm_DestroyNodesInRadius(float x, float y, float radius); SILKWORMAPI void Silkworm_DestroyNodesInRectangle(Silkworm_Rectangle* rectangle); +SILKWORMAPI uint32_t Silkworm_DestroyedNodeCount(); +SILKWORMAPI uint32_t Silkworm_DestroyedLinkCount(); + SILKWORMAPI void Silkworm_PerformDestroys(); SILKWORMAPI void Silkworm_ClearAll(); SILKWORMAPI void Silkworm_Finish();