bunch of new cloth API stuff
							parent
							
								
									7fe8190a0e
								
							
						
					
					
						commit
						a479c66969
					
				
							
								
								
									
										334
									
								
								src/Silkworm.c
								
								
								
								
							
							
						
						
									
										334
									
								
								src/Silkworm.c
								
								
								
								
							| 
						 | 
					@ -47,18 +47,19 @@ typedef struct Silkworm_Context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Silkworm_Cloth** cloths;
 | 
						Silkworm_Cloth** cloths;
 | 
				
			||||||
	uint32_t clothCount;
 | 
						uint32_t clothCount;
 | 
				
			||||||
 | 
						uint32_t clothCapacity;
 | 
				
			||||||
	uint64_t* nodeIndicesToDestroy;
 | 
					 | 
				
			||||||
	uint32_t nodeIndicesToDestroyCount;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint64_t* linkIndicesToDestroy;
 | 
					 | 
				
			||||||
	uint32_t linkIndicesToDestroyCount;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t* nodeIndexStack;
 | 
						uint64_t* nodeIndexStack;
 | 
				
			||||||
	uint32_t nodeIndexStackCount;
 | 
						uint32_t nodeIndexStackCount;
 | 
				
			||||||
 | 
						uint32_t nodeIndexStackCapacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t* linkIndexStack;
 | 
						uint64_t* linkIndexStack;
 | 
				
			||||||
	uint32_t linkIndexStackCount;
 | 
						uint32_t linkIndexStackCount;
 | 
				
			||||||
 | 
						uint32_t linkIndexStackCapacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t* clothIndexStack;
 | 
				
			||||||
 | 
						uint32_t clothIndexStackCount;
 | 
				
			||||||
 | 
						uint32_t clothIndexStackCapacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float gravity;
 | 
						float gravity;
 | 
				
			||||||
	float xBound;
 | 
						float xBound;
 | 
				
			||||||
| 
						 | 
					@ -78,30 +79,167 @@ void Silkworm_Init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context->nodes = NULL;
 | 
						context->nodes = NULL;
 | 
				
			||||||
	context->nodeCount = 0;
 | 
						context->nodeCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context->links = NULL;
 | 
						context->links = NULL;
 | 
				
			||||||
	context->linkCount = 0;
 | 
						context->linkCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context->nodeIndicesToDestroy = NULL;
 | 
					 | 
				
			||||||
	context->nodeIndicesToDestroyCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	context->linkIndicesToDestroy = NULL;
 | 
					 | 
				
			||||||
	context->linkIndicesToDestroyCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	context->nodeIndexStack = NULL;
 | 
					 | 
				
			||||||
	context->nodeIndexStackCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	context->linkIndexStack = NULL;
 | 
					 | 
				
			||||||
	context->linkIndexStackCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	context->cloths = NULL;
 | 
						context->cloths = NULL;
 | 
				
			||||||
	context->clothCount = 0;
 | 
						context->clothCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->nodeIndexStackCapacity = 16;
 | 
				
			||||||
 | 
						context->nodeIndexStack = malloc(sizeof(uint64_t) * context->nodeIndexStackCapacity);
 | 
				
			||||||
 | 
						context->nodeIndexStackCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->linkIndexStackCapacity = 16;
 | 
				
			||||||
 | 
						context->linkIndexStack = malloc(sizeof(uint64_t) * context->linkIndexStackCapacity);
 | 
				
			||||||
 | 
						context->linkIndexStackCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->clothIndexStackCapacity = 16;
 | 
				
			||||||
 | 
						context->clothIndexStack = malloc(sizeof(uint64_t) * context->clothIndexStackCapacity);
 | 
				
			||||||
 | 
						context->clothIndexStackCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context->gravity = 200;
 | 
						context->gravity = 200;
 | 
				
			||||||
	context->xBound = 1000;
 | 
						context->xBound = 1000;
 | 
				
			||||||
	context->yBound = 1000;
 | 
						context->yBound = 1000;
 | 
				
			||||||
	context->clothDensity = 4;
 | 
						context->clothDensity = 4;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline Silkworm_Node* LookupNode(uint64_t nodeId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return context->nodes[nodeId];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline Silkworm_Link* LookupLink(uint64_t linkId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return context->links[linkId];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline Silkworm_Cloth* LookupCloth(uint64_t clothId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return context->cloths[clothId];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* we defer actual destruction to Update to avoid issues with NULL */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_DestroyNode(double nodeId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
						Silkworm_Node* node = LookupNode((uint64_t)nodeId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (node != NULL)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							node->markedForDestroy = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < node->linkCount; i += 1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (node->links[i] != NULL)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									node->links[i]->markedForDestroy = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_Internal_DestroyLink(Silkworm_Link* link)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						link->markedForDestroy = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_DestroyLink(double linkId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Silkworm_Internal_DestroyLink(LookupLink((uint64_t)linkId));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->cloths[cloth->id] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < cloth->horizontalNodeCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (j = 0; j < cloth->verticalNodeCount; j += 1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Silkworm_DestroyNode((double)cloth->nodeIndices[i][j]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							free(cloth->nodeIndices[i]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						free(cloth->nodeIndices);
 | 
				
			||||||
 | 
						free(cloth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (context->clothIndexStackCount >= context->clothIndexStackCapacity)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							context->clothIndexStackCapacity *= 2;
 | 
				
			||||||
 | 
							context->nodeIndexStack = realloc(context->nodeIndexStack, sizeof(uint64_t) * context->nodeIndexStackCapacity);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->clothIndexStack[context->clothIndexStackCount] = cloth->id;
 | 
				
			||||||
 | 
						context->clothIndexStackCount += 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_DestroyCloth(double clothId)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Silkworm_Internal_DestroyCloth(LookupCloth((uint64_t)clothId));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_PerformDestroys()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i, j;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < context->linkCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (context->links[i] != NULL && context->links[i]->markedForDestroy)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								for (j = 0; j < context->links[i]->a->linkCount; j += 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (context->links[i]->a->links[j] == context->links[i])
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										context->links[i]->a->links[j] = NULL;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (j = 0; j < context->links[i]->b->linkCount; j += 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (context->links[i]->b->links[j] == context->links[i])
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										context->links[i]->b->links[j] = NULL;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								free(context->links[i]);
 | 
				
			||||||
 | 
								context->links[i] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (context->linkIndexStackCount >= context->linkIndexStackCapacity)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									context->linkIndexStackCapacity *= 2;
 | 
				
			||||||
 | 
									context->linkIndexStack = realloc(context->linkIndexStack, sizeof(uint64_t) * context->linkIndexStackCapacity);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								context->linkIndexStack[context->linkIndexStackCount] = i;
 | 
				
			||||||
 | 
								context->linkIndexStackCount += 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < context->nodeCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (context->nodes[i] != NULL && context->nodes[i]->markedForDestroy)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								free(context->nodes[i]->links);
 | 
				
			||||||
 | 
								free(context->nodes[i]);
 | 
				
			||||||
 | 
								context->nodes[i] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (context->nodeIndexStackCount >= context->nodeIndexStackCapacity)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									context->nodeIndexStackCapacity *= 2;
 | 
				
			||||||
 | 
									context->nodeIndexStack = realloc(context->nodeIndexStack, sizeof(uint64_t) * context->nodeIndexStackCapacity);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								context->nodeIndexStack[context->nodeIndexStackCount] = i;
 | 
				
			||||||
 | 
								context->nodeIndexStackCount += 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Silkworm_Update(double deltaTime)
 | 
					void Silkworm_Update(double deltaTime)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i, j;
 | 
						uint32_t i, j;
 | 
				
			||||||
| 
						 | 
					@ -131,9 +269,7 @@ void Silkworm_Update(double deltaTime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (distanceMoved > link->tearThreshold)
 | 
									if (distanceMoved > link->tearThreshold)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					context->linkIndicesToDestroy = realloc(context->linkIndicesToDestroy, sizeof(uint64_t) * (context->linkIndicesToDestroyCount + 1));
 | 
										Silkworm_DestroyLink((double)link->id);
 | 
				
			||||||
					context->linkIndicesToDestroy[context->linkIndicesToDestroyCount] = link->id;
 | 
					 | 
				
			||||||
					context->linkIndicesToDestroyCount += 1;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
| 
						 | 
					@ -151,7 +287,6 @@ void Silkworm_Update(double deltaTime)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (j = 0; j < context->nodeCount; j += 1)
 | 
						for (j = 0; j < context->nodeCount; j += 1)
 | 
				
			||||||
| 
						 | 
					@ -179,50 +314,13 @@ void Silkworm_Update(double deltaTime)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (fabs(node->position.x) > context->xBound || fabs(node->position.x) > context->yBound)
 | 
									if (fabs(node->position.x) > context->xBound || fabs(node->position.x) > context->yBound)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					context->nodeIndicesToDestroy = realloc(context->nodeIndicesToDestroy, sizeof(uint64_t) * (context->nodeIndicesToDestroyCount + 1));
 | 
										Silkworm_DestroyNode((double)node->id);
 | 
				
			||||||
					context->nodeIndicesToDestroy[context->nodeIndicesToDestroyCount] = node->id;
 | 
					 | 
				
			||||||
					context->nodeIndicesToDestroyCount += 1;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (j = 0; j < context->nodeIndicesToDestroyCount; j += 1)
 | 
						Silkworm_PerformDestroys();
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		uint64_t nodeIndex = context->nodeIndicesToDestroy[j];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		free(context->nodes[nodeIndex]);
 | 
					 | 
				
			||||||
		context->nodes[nodeIndex] = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		context->nodeIndexStack = realloc(context->nodeIndexStack, sizeof(uint64_t) * (context->nodeIndexStackCount + 1));
 | 
					 | 
				
			||||||
		context->nodeIndexStack[context->nodeIndexStackCount] = nodeIndex;
 | 
					 | 
				
			||||||
		context->nodeIndexStackCount += 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for (j = 0; j < context->linkIndicesToDestroyCount; j += 1)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		uint64_t linkIndex = context->linkIndicesToDestroy[j];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		free(context->links[linkIndex]);
 | 
					 | 
				
			||||||
		context->links[linkIndex] = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		context->linkIndexStack = realloc(context->linkIndexStack, sizeof(uint64_t) * (context->linkIndexStackCount + 1));
 | 
					 | 
				
			||||||
		context->linkIndexStack[context->linkIndexStackCount] = linkIndex;
 | 
					 | 
				
			||||||
		context->linkIndexStackCount += 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	context->nodeIndicesToDestroyCount = 0;
 | 
					 | 
				
			||||||
	context->linkIndicesToDestroyCount = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline Silkworm_Node* LookupNode(double nodeId)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return context->nodes[(uint64_t)nodeId];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline Silkworm_Cloth* LookupCloth(double clothId)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return context->cloths[(uint64_t)clothId];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor)
 | 
					double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor)
 | 
				
			||||||
| 
						 | 
					@ -233,20 +331,18 @@ double Silkworm_CreateNode(double xPosition, double yPosition, double mass, doub
 | 
				
			||||||
	if (context->nodeIndexStackCount > 0)
 | 
						if (context->nodeIndexStackCount > 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		id = context->nodeIndexStack[context->nodeIndexStackCount - 1];
 | 
							id = context->nodeIndexStack[context->nodeIndexStackCount - 1];
 | 
				
			||||||
		context->nodeIndexStack = realloc(context->nodeIndexStack, sizeof(uint64_t) * (context->nodeIndexStackCount - 1));
 | 
					 | 
				
			||||||
		context->nodeIndexStackCount -= 1;
 | 
							context->nodeIndexStackCount -= 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		context->nodes[id] = node;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		id = context->nodeCount;
 | 
							id = context->nodeCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		context->nodes = realloc(context->nodes, sizeof(Silkworm_Node*) * (context->nodeCount + 1));
 | 
							context->nodes = realloc(context->nodes, sizeof(Silkworm_Node*) * (context->nodeCount + 1));
 | 
				
			||||||
		context->nodes[context->nodeCount] = node;
 | 
					 | 
				
			||||||
		context->nodeCount += 1;
 | 
							context->nodeCount += 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->nodes[id] = node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node->id = id;
 | 
						node->id = id;
 | 
				
			||||||
	node->position.x = (float)xPosition;
 | 
						node->position.x = (float)xPosition;
 | 
				
			||||||
	node->position.y = (float)yPosition;
 | 
						node->position.y = (float)yPosition;
 | 
				
			||||||
| 
						 | 
					@ -262,6 +358,9 @@ double Silkworm_CreateNode(double xPosition, double yPosition, double mass, doub
 | 
				
			||||||
	node->pushFactor = (float)pushFactor;
 | 
						node->pushFactor = (float)pushFactor;
 | 
				
			||||||
	node->pinned = false;
 | 
						node->pinned = false;
 | 
				
			||||||
	node->destroyable = false;
 | 
						node->destroyable = false;
 | 
				
			||||||
 | 
						node->markedForDestroy = false;
 | 
				
			||||||
 | 
						node->links = NULL;
 | 
				
			||||||
 | 
						node->linkCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (double)node->id;
 | 
						return (double)node->id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -295,6 +394,29 @@ void Silkworm_ClothNodeUnpin(double clothId, double i, double j)
 | 
				
			||||||
	context->nodes[cloth->nodeIndices[(uint64_t)i][(uint64_t)j]]->pinned = false;
 | 
						context->nodes[cloth->nodeIndices[(uint64_t)i][(uint64_t)j]]->pinned = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_ClothNodeDestroy(double clothId, double i, double j)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Silkworm_Cloth* cloth = LookupCloth(clothId);
 | 
				
			||||||
 | 
						uint64_t nodeIndex = cloth->nodeIndices[(uint64_t)i][(uint64_t)j];
 | 
				
			||||||
 | 
						Silkworm_Node* node = context->nodes[nodeIndex];
 | 
				
			||||||
 | 
						Silkworm_DestroyNode(nodeIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* fixme: this should be hashed */
 | 
				
			||||||
 | 
						for (iterator = 0; iterator < cloth->triangleCount; iterator += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (cloth->triangles[iterator] != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (cloth->triangles[iterator]->a == node || cloth->triangles[iterator]->b == node || cloth->triangles[iterator]->c == node)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									free(cloth->triangles[iterator]);
 | 
				
			||||||
 | 
									cloth->triangles[iterator] = NULL;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold)
 | 
					double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Silkworm_Node *nodeA = LookupNode(aId);
 | 
						Silkworm_Node *nodeA = LookupNode(aId);
 | 
				
			||||||
| 
						 | 
					@ -307,25 +429,32 @@ double Silkworm_CreateLink(double aId, double bId, double distance, double tearT
 | 
				
			||||||
	if (context->linkIndexStackCount > 0)
 | 
						if (context->linkIndexStackCount > 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		id = context->linkIndexStack[context->linkIndexStackCount - 1];
 | 
							id = context->linkIndexStack[context->linkIndexStackCount - 1];
 | 
				
			||||||
		context->linkIndexStack = realloc(context->linkIndexStack, sizeof(uint64_t) * (context->linkIndexStackCount - 1));
 | 
					 | 
				
			||||||
		context->linkIndexStackCount -= 1;
 | 
							context->linkIndexStackCount -= 1;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		context->links[id] = link;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else 
 | 
						else 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		id = context->linkCount;
 | 
							id = context->linkCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		context->links = realloc(context->links, sizeof(Silkworm_Link*) * (context->linkCount + 1));
 | 
							context->links = realloc(context->links, sizeof(Silkworm_Link*) * (context->linkCount + 1));
 | 
				
			||||||
		context->links[context->linkCount] = link;
 | 
					 | 
				
			||||||
		context->linkCount += 1;
 | 
							context->linkCount += 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						context->links[id] = link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	link->id = id;
 | 
						link->id = id;
 | 
				
			||||||
	link->a = nodeA;
 | 
						link->a = nodeA;
 | 
				
			||||||
	link->b = nodeB;
 | 
						link->b = nodeB;
 | 
				
			||||||
	link->distance = (float)distance;
 | 
						link->distance = (float)distance;
 | 
				
			||||||
	link->tearThreshold = (float)tearThreshold;
 | 
						link->tearThreshold = (float)tearThreshold;
 | 
				
			||||||
 | 
						link->markedForDestroy = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link->a->links = realloc(link->a->links, sizeof(Silkworm_Link*) * (link->a->linkCount + 1));
 | 
				
			||||||
 | 
						link->a->links[link->a->linkCount] = link;
 | 
				
			||||||
 | 
						link->a->linkCount += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						link->b->links = realloc(link->b->links, sizeof(Silkworm_Link*) * (link->b->linkCount + 1));
 | 
				
			||||||
 | 
						link->b->links[link->b->linkCount] = link;
 | 
				
			||||||
 | 
						link->b->linkCount += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (double)link->id;
 | 
						return (double)link->id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -341,10 +470,25 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double horizonta
 | 
				
			||||||
	cloth->verticalNodeCount = (uint32_t) verticalNodeCount;
 | 
						cloth->verticalNodeCount = (uint32_t) verticalNodeCount;
 | 
				
			||||||
	cloth->nodeIndices = malloc(sizeof(uint64_t*) * cloth->horizontalNodeCount);
 | 
						cloth->nodeIndices = malloc(sizeof(uint64_t*) * cloth->horizontalNodeCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cloth->id = context->clothCount;
 | 
						uint64_t id;
 | 
				
			||||||
	context->cloths = realloc(context->cloths, sizeof(Silkworm_Cloth*) * (context->clothCount + 1));
 | 
					
 | 
				
			||||||
	context->cloths[context->clothCount] = cloth;
 | 
						if (context->clothIndexStackCount > 0)
 | 
				
			||||||
	context->clothCount += 1;
 | 
						{
 | 
				
			||||||
 | 
							id = context->clothIndexStack[context->clothIndexStackCount - 1];
 | 
				
			||||||
 | 
							context->clothIndexStackCount -= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							context->cloths[id] = cloth;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							id = context->clothCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							context->cloths = realloc(context->cloths, sizeof(Silkworm_Cloth*) * (context->clothCount + 1));
 | 
				
			||||||
 | 
							context->cloths[id] = cloth;
 | 
				
			||||||
 | 
							context->clothCount += 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cloth->id = id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < horizontalNodeCount; i += 1)
 | 
						for (i = 0; i < horizontalNodeCount; i += 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -437,6 +581,35 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double horizonta
 | 
				
			||||||
	return (double)cloth->id;
 | 
						return (double)cloth->id;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_ApplyWind(double xSpeed, double ySpeed)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i, j, k;
 | 
				
			||||||
 | 
						Silkworm_Cloth* cloth;
 | 
				
			||||||
 | 
						Silkworm_Node* node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < context->clothCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (context->cloths[i] != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cloth = context->cloths[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								for (j = 0; j < cloth->horizontalNodeCount; j += 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									for (k = 0; k < cloth->verticalNodeCount; k += 1)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										node = context->nodes[cloth->nodeIndices[j][k]];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										if (node != NULL && !node->pinned)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											node->position.x += (float)xSpeed * 0.05f * cloth->windFactor;
 | 
				
			||||||
 | 
											node->position.y += (float)ySpeed * 0.05f * cloth->windFactor;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Silkworm_SetTriangleBuffer(const char* bufferId)
 | 
					void Silkworm_SetTriangleBuffer(const char* bufferId)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	context->currentBufferAddress = (uint8_t*)bufferId;
 | 
						context->currentBufferAddress = (uint8_t*)bufferId;
 | 
				
			||||||
| 
						 | 
					@ -557,3 +730,18 @@ double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double wi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (double)triangleCount;
 | 
						return (double)triangleCount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_ClearAll()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for (i = 0; i < context->clothCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (context->cloths[i] != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Silkworm_Internal_DestroyCloth(context->cloths[i]);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Silkworm_PerformDestroys();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ typedef struct Silkworm_Vector2
 | 
				
			||||||
	float y;
 | 
						float y;
 | 
				
			||||||
} Silkworm_Vector2;
 | 
					} Silkworm_Vector2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Link Silkworm_Link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Silkworm_Node
 | 
					typedef struct Silkworm_Node
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint64_t id;
 | 
						uint64_t id;
 | 
				
			||||||
| 
						 | 
					@ -62,16 +64,23 @@ typedef struct Silkworm_Node
 | 
				
			||||||
	float pinned;
 | 
						float pinned;
 | 
				
			||||||
	float pushFactor;
 | 
						float pushFactor;
 | 
				
			||||||
	bool destroyable;
 | 
						bool destroyable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Silkworm_Link** links;
 | 
				
			||||||
 | 
						uint32_t linkCount;
 | 
				
			||||||
} Silkworm_Node;
 | 
					} Silkworm_Node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Silkworm_Link
 | 
					struct Silkworm_Link
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint64_t id;
 | 
						uint64_t id;
 | 
				
			||||||
	Silkworm_Node *a;
 | 
						Silkworm_Node *a;
 | 
				
			||||||
	Silkworm_Node *b;
 | 
						Silkworm_Node *b;
 | 
				
			||||||
	float distance;
 | 
						float distance;
 | 
				
			||||||
	float tearThreshold;
 | 
						float tearThreshold;
 | 
				
			||||||
} Silkworm_Link;
 | 
					
 | 
				
			||||||
 | 
						bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum Silkworm_ClothTriangleOrientation
 | 
					typedef enum Silkworm_ClothTriangleOrientation
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -133,18 +142,25 @@ typedef struct Silkworm_Rope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_Init();
 | 
					SILKWORMAPI void Silkworm_Init();
 | 
				
			||||||
SILKWORMAPI void Silkworm_Update(double delta);
 | 
					SILKWORMAPI void Silkworm_Update(double delta);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_ApplyWind(double xSpeed, double ySpeed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor);
 | 
					SILKWORMAPI double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId);
 | 
					SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId);
 | 
				
			||||||
SILKWORMAPI void Silkworm_ClothNodePin(double clothId, double i, double j);
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_ClothNodeUnpin(double clothId, double i, double j);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold);
 | 
					SILKWORMAPI double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI double Silkworm_CreateCloth(double xPosition, double yPosition, double horizontalNodeCount, double verticalNodeCount, double mass, double friction, double windFactor, double tearThreshold);
 | 
					SILKWORMAPI double Silkworm_CreateCloth(double xPosition, double yPosition, double horizontalNodeCount, double verticalNodeCount, double mass, double friction, double windFactor, double tearThreshold);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_ClothNodePin(double clothId, double i, double j);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_ClothNodeUnpin(double clothId, double i, double j);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_ClothNodeDestroy(double clothId, double i, double j);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_DestroyCloth(double clothId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_SetTriangleBuffer(const char* bufferId);
 | 
					SILKWORMAPI void Silkworm_SetTriangleBuffer(const char* bufferId);
 | 
				
			||||||
SILKWORMAPI double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double widthUV, double topUV, double heightUV);
 | 
					SILKWORMAPI double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double widthUV, double topUV, double heightUV);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_DestroyNode(double nodeId);
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_ClearAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SILKWORM_H */
 | 
					#endif /* SILKWORM_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue