node to triangle lookups
							parent
							
								
									a479c66969
								
							
						
					
					
						commit
						2fc8d0a781
					
				
							
								
								
									
										259
									
								
								src/Silkworm.c
								
								
								
								
							
							
						
						
									
										259
									
								
								src/Silkworm.c
								
								
								
								
							| 
						 | 
					@ -29,6 +29,174 @@
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Vector2
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						float x;
 | 
				
			||||||
 | 
						float y;
 | 
				
			||||||
 | 
					} Silkworm_Vector2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Link Silkworm_Link;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Node
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t id;
 | 
				
			||||||
 | 
						Silkworm_Vector2 position;
 | 
				
			||||||
 | 
						Silkworm_Vector2 previousPosition;
 | 
				
			||||||
 | 
						Silkworm_Vector2 velocity;
 | 
				
			||||||
 | 
						Silkworm_Vector2 acceleration;
 | 
				
			||||||
 | 
						float mass;
 | 
				
			||||||
 | 
						float friction;
 | 
				
			||||||
 | 
						float radius;
 | 
				
			||||||
 | 
						float pinned;
 | 
				
			||||||
 | 
						float pushFactor;
 | 
				
			||||||
 | 
						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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct Silkworm_Link
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t id;
 | 
				
			||||||
 | 
						Silkworm_Node* a;
 | 
				
			||||||
 | 
						Silkworm_Node* b;
 | 
				
			||||||
 | 
						float distance;
 | 
				
			||||||
 | 
						float tearThreshold;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum Silkworm_ClothTriangleOrientation
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						UpperLeft,
 | 
				
			||||||
 | 
						BottomRight
 | 
				
			||||||
 | 
					} Silkworm_ClothTriangleOrientation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Triangle
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t id;
 | 
				
			||||||
 | 
						Silkworm_Node* a;
 | 
				
			||||||
 | 
						Silkworm_Node* b;
 | 
				
			||||||
 | 
						Silkworm_Node* c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t aHorizontalIndex;
 | 
				
			||||||
 | 
						uint32_t bHorizontalIndex;
 | 
				
			||||||
 | 
						uint32_t cHorizontalIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t aVerticalIndex;
 | 
				
			||||||
 | 
						uint32_t bVerticalIndex;
 | 
				
			||||||
 | 
						uint32_t cVerticalIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Silkworm_ClothTriangleOrientation orientation;
 | 
				
			||||||
 | 
					} Silkworm_Triangle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct NodeTriangleHashMap
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Silkworm_Node* key;
 | 
				
			||||||
 | 
						uint32_t *indexArray;
 | 
				
			||||||
 | 
						uint32_t indexArrayCount;
 | 
				
			||||||
 | 
					} NodeTriangleHashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct NodeTriangleHashArray
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						NodeTriangleHashMap* elements;
 | 
				
			||||||
 | 
						uint32_t count;
 | 
				
			||||||
 | 
					} NodeTriangleHashArray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NUM_NODE_TRIANGLE_HASH_BUCKETS 1031
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct NodeTriangleHashTable
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						NodeTriangleHashArray buckets[NUM_NODE_TRIANGLE_HASH_BUCKETS];
 | 
				
			||||||
 | 
					} NodeTriangleHashTable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint64_t NodeTriangleHashTable_GetHashCode(Silkworm_Node *key)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return 97 + (uint64_t)(size_t)key;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t* NodeTriangleHashTable_Fetch(
 | 
				
			||||||
 | 
						NodeTriangleHashTable *table,
 | 
				
			||||||
 | 
						Silkworm_Node *key,
 | 
				
			||||||
 | 
						uint32_t *arrayCount
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
						uint64_t hashcode = NodeTriangleHashTable_GetHashCode(key);
 | 
				
			||||||
 | 
						NodeTriangleHashArray* arr = &table->buckets[hashcode % NUM_NODE_TRIANGLE_HASH_BUCKETS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < arr->count; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (arr->elements[i].key == key)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								*arrayCount = arr->elements[i].indexArrayCount;
 | 
				
			||||||
 | 
								return arr->elements[i].indexArray;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*arrayCount = 0;
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void NodeTriangleHashTable_Insert(
 | 
				
			||||||
 | 
						NodeTriangleHashTable* table,
 | 
				
			||||||
 | 
						Silkworm_Node* key,
 | 
				
			||||||
 | 
						uint32_t index
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
						uint64_t hashcode = NodeTriangleHashTable_GetHashCode(key);
 | 
				
			||||||
 | 
						NodeTriangleHashArray* arr = &table->buckets[hashcode % NUM_NODE_TRIANGLE_HASH_BUCKETS];
 | 
				
			||||||
 | 
						bool foundKey = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < arr->count; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (arr->elements[i].key == key)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								arr->elements[i].indexArray = 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;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!foundKey)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							arr->elements = realloc(arr->elements, sizeof(NodeTriangleHashMap) * (arr->count + 1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							arr->elements[arr->count].key = key;
 | 
				
			||||||
 | 
							arr->elements[arr->count].indexArray = malloc(sizeof(uint32_t));
 | 
				
			||||||
 | 
							arr->elements[arr->count].indexArray[0] = index;
 | 
				
			||||||
 | 
							arr->elements[arr->count].indexArrayCount = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							arr->count += 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Cloth
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint64_t id;
 | 
				
			||||||
 | 
						float windFactor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t horizontalNodeCount;
 | 
				
			||||||
 | 
						uint32_t verticalNodeCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t** nodeIndices; /* x by y grid of indices */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Silkworm_Triangle** triangles; /* array of pointers so we can use NULL */
 | 
				
			||||||
 | 
						uint32_t triangleCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						NodeTriangleHashTable nodeHash;
 | 
				
			||||||
 | 
					} Silkworm_Cloth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct Silkworm_Rope
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t nodeCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t* nodeIndices;
 | 
				
			||||||
 | 
					} Silkworm_Rope;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Silkworm_Color
 | 
					typedef struct Silkworm_Color
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint8_t r;
 | 
						uint8_t r;
 | 
				
			||||||
| 
						 | 
					@ -156,6 +324,15 @@ void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	context->cloths[cloth->id] = NULL;
 | 
						context->cloths[cloth->id] = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < NUM_NODE_TRIANGLE_HASH_BUCKETS; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							for (j = 0; j < cloth->nodeHash.buckets[i].count; j += 1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								free(cloth->nodeHash.buckets[i].elements[j].indexArray);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							free(cloth->nodeHash.buckets[i].elements);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < cloth->horizontalNodeCount; i += 1)
 | 
						for (i = 0; i < cloth->horizontalNodeCount; i += 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for (j = 0; j < cloth->verticalNodeCount; j += 1)
 | 
							for (j = 0; j < cloth->verticalNodeCount; j += 1)
 | 
				
			||||||
| 
						 | 
					@ -184,7 +361,7 @@ void Silkworm_DestroyCloth(double clothId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Silkworm_PerformDestroys()
 | 
					void Silkworm_PerformDestroys()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i, j;
 | 
						uint32_t i, j, k;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < context->linkCount; i += 1)
 | 
						for (i = 0; i < context->linkCount; i += 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -222,8 +399,32 @@ void Silkworm_PerformDestroys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < context->nodeCount; i += 1)
 | 
						for (i = 0; i < context->nodeCount; i += 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (context->nodes[i] != NULL && context->nodes[i]->markedForDestroy)
 | 
							Silkworm_Node* node = context->nodes[i];
 | 
				
			||||||
 | 
							if (node != NULL && node->markedForDestroy)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								/* find cloth to remove from relevant triangles */
 | 
				
			||||||
 | 
								for (j = 0; j < context->clothCount; j += 1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Silkworm_Cloth* cloth = context->cloths[j];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (cloth != NULL)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										uint32_t triangleIndexCount = 0;
 | 
				
			||||||
 | 
										uint32_t* triangleIndices = NodeTriangleHashTable_Fetch(&cloth->nodeHash, node, &triangleIndexCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										for (k = 0; k < triangleIndexCount; k += 1)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											uint32_t triangleIndex = triangleIndices[k];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											if (cloth->triangles[triangleIndex] != NULL)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												free(cloth->triangles[triangleIndex]);
 | 
				
			||||||
 | 
												cloth->triangles[triangleIndex] = NULL;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			free(context->nodes[i]->links);
 | 
								free(context->nodes[i]->links);
 | 
				
			||||||
			free(context->nodes[i]);
 | 
								free(context->nodes[i]);
 | 
				
			||||||
			context->nodes[i] = NULL;
 | 
								context->nodes[i] = NULL;
 | 
				
			||||||
| 
						 | 
					@ -396,25 +597,10 @@ void Silkworm_ClothNodeUnpin(double clothId, double i, double j)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Silkworm_ClothNodeDestroy(double clothId, double i, double j)
 | 
					void Silkworm_ClothNodeDestroy(double clothId, double i, double j)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t iterator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Silkworm_Cloth* cloth = LookupCloth(clothId);
 | 
						Silkworm_Cloth* cloth = LookupCloth(clothId);
 | 
				
			||||||
	uint64_t nodeIndex = cloth->nodeIndices[(uint64_t)i][(uint64_t)j];
 | 
						uint64_t nodeIndex = cloth->nodeIndices[(uint64_t)i][(uint64_t)j];
 | 
				
			||||||
	Silkworm_Node* node = context->nodes[nodeIndex];
 | 
						Silkworm_Node* node = context->nodes[nodeIndex];
 | 
				
			||||||
	Silkworm_DestroyNode(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)
 | 
				
			||||||
| 
						 | 
					@ -490,6 +676,12 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double horizonta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cloth->id = id;
 | 
						cloth->id = id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < NUM_NODE_TRIANGLE_HASH_BUCKETS; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							cloth->nodeHash.buckets[i].elements = NULL;
 | 
				
			||||||
 | 
							cloth->nodeHash.buckets[i].count = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (i = 0; i < horizontalNodeCount; i += 1)
 | 
						for (i = 0; i < horizontalNodeCount; i += 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		cloth->nodeIndices[i] = malloc(sizeof(uint64_t) * cloth->verticalNodeCount);
 | 
							cloth->nodeIndices[i] = malloc(sizeof(uint64_t) * cloth->verticalNodeCount);
 | 
				
			||||||
| 
						 | 
					@ -534,6 +726,10 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double horizonta
 | 
				
			||||||
				cloth->triangles[triangleIndex]->cHorizontalIndex = i;
 | 
									cloth->triangles[triangleIndex]->cHorizontalIndex = i;
 | 
				
			||||||
				cloth->triangles[triangleIndex]->cVerticalIndex = j + 1;
 | 
									cloth->triangles[triangleIndex]->cVerticalIndex = j + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i][j]], triangleIndex);
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i + 1][j]], triangleIndex);
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i][j + 1]], triangleIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				triangleIndex += 1;
 | 
									triangleIndex += 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -555,6 +751,10 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double horizonta
 | 
				
			||||||
				cloth->triangles[triangleIndex]->cHorizontalIndex = i;
 | 
									cloth->triangles[triangleIndex]->cHorizontalIndex = i;
 | 
				
			||||||
				cloth->triangles[triangleIndex]->cVerticalIndex = j - 1;
 | 
									cloth->triangles[triangleIndex]->cVerticalIndex = j - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i][j]], triangleIndex);
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i - 1][j]], triangleIndex);
 | 
				
			||||||
 | 
									NodeTriangleHashTable_Insert(&cloth->nodeHash, context->nodes[cloth->nodeIndices[i][j - 1]], triangleIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				triangleIndex += 1;
 | 
									triangleIndex += 1;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -731,6 +931,31 @@ double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double wi
 | 
				
			||||||
	return (double)triangleCount;
 | 
						return (double)triangleCount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* TODO: spatial hash implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < context->nodeCount; i += 1)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Silkworm_Node* node = context->nodes[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (node != NULL)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								float xDistance = (float)fabs((float)x - node->position.x);
 | 
				
			||||||
 | 
								float yDistance = (float)fabs((float)y - node->position.y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								float squareDistance = xDistance * xDistance + yDistance * yDistance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (squareDistance <= radius * radius)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Silkworm_DestroyNode(i);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Silkworm_ClearAll()
 | 
					void Silkworm_ClearAll()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uint32_t i;
 | 
						uint32_t i;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,90 +43,6 @@
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif /* __cplusplus */
 | 
					#endif /* __cplusplus */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Silkworm_Vector2
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	float x;
 | 
					 | 
				
			||||||
	float y;
 | 
					 | 
				
			||||||
} Silkworm_Vector2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Silkworm_Link Silkworm_Link;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Silkworm_Node
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint64_t id;
 | 
					 | 
				
			||||||
	Silkworm_Vector2 position;
 | 
					 | 
				
			||||||
	Silkworm_Vector2 previousPosition;
 | 
					 | 
				
			||||||
	Silkworm_Vector2 velocity;
 | 
					 | 
				
			||||||
	Silkworm_Vector2 acceleration;
 | 
					 | 
				
			||||||
	float mass;
 | 
					 | 
				
			||||||
	float friction;
 | 
					 | 
				
			||||||
	float radius;
 | 
					 | 
				
			||||||
	float pinned;
 | 
					 | 
				
			||||||
	float pushFactor;
 | 
					 | 
				
			||||||
	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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct Silkworm_Link
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint64_t id;
 | 
					 | 
				
			||||||
	Silkworm_Node *a;
 | 
					 | 
				
			||||||
	Silkworm_Node *b;
 | 
					 | 
				
			||||||
	float distance;
 | 
					 | 
				
			||||||
	float tearThreshold;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum Silkworm_ClothTriangleOrientation
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	UpperLeft,
 | 
					 | 
				
			||||||
	BottomRight
 | 
					 | 
				
			||||||
} Silkworm_ClothTriangleOrientation;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Silkworm_Triangle
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint64_t id;
 | 
					 | 
				
			||||||
	Silkworm_Node* a;
 | 
					 | 
				
			||||||
	Silkworm_Node* b;
 | 
					 | 
				
			||||||
	Silkworm_Node* c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t aHorizontalIndex;
 | 
					 | 
				
			||||||
	uint32_t bHorizontalIndex;
 | 
					 | 
				
			||||||
	uint32_t cHorizontalIndex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t aVerticalIndex;
 | 
					 | 
				
			||||||
	uint32_t bVerticalIndex;
 | 
					 | 
				
			||||||
	uint32_t cVerticalIndex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Silkworm_ClothTriangleOrientation orientation;
 | 
					 | 
				
			||||||
} Silkworm_Triangle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Silkworm_Cloth
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint64_t id;
 | 
					 | 
				
			||||||
	float windFactor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t horizontalNodeCount;
 | 
					 | 
				
			||||||
	uint32_t verticalNodeCount;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint64_t **nodeIndices; /* x by y grid of indices */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Silkworm_Triangle **triangles; /* array of pointers so we can use NULL */
 | 
					 | 
				
			||||||
	uint32_t triangleCount;
 | 
					 | 
				
			||||||
} Silkworm_Cloth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Silkworm_Rope
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint32_t nodeCount;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t *nodeIndices;
 | 
					 | 
				
			||||||
} Silkworm_Rope;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Version API */
 | 
					/* Version API */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SILKWORM_ABI_VERSION	 0
 | 
					#define SILKWORM_ABI_VERSION	 0
 | 
				
			||||||
| 
						 | 
					@ -148,7 +64,6 @@ SILKWORMAPI double Silkworm_CreateNode(double xPosition, double yPosition, doubl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId);
 | 
					SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
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);
 | 
				
			||||||
| 
						 | 
					@ -161,6 +76,9 @@ 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_DestroyNode(double nodeId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SILKWORMAPI void Silkworm_DestroyNodesInRadius(double x, double y, double radius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SILKWORMAPI void Silkworm_ClearAll();
 | 
					SILKWORMAPI void Silkworm_ClearAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SILKWORM_H */
 | 
					#endif /* SILKWORM_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue