From 40b3a6596d4618d48ed312c7d200379cdad121be Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 22 Sep 2021 17:28:47 -0700 Subject: [PATCH] implement most of the library! --- .gitignore | 2 + src/Silkworm.c | 548 ++++++++++++++++++++++++++++++++------- src/Silkworm.h | 93 ++++--- visualc/Silkworm.vcxproj | 10 +- 4 files changed, 524 insertions(+), 129 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..205d786 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +visualc/.vs +visualc/x64 diff --git a/src/Silkworm.c b/src/Silkworm.c index f8fa6d8..6af7833 100644 --- a/src/Silkworm.c +++ b/src/Silkworm.c @@ -27,11 +27,45 @@ #include "Silkworm.h" #include +#include + +typedef struct Silkworm_Color +{ + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; +} Silkworm_Color; typedef struct Silkworm_Context { - Silkworm_Group **groups; - uint32_t groupCount; + Silkworm_Node** nodes; + uint32_t nodeCount; + + Silkworm_Link** links; + uint32_t linkCount; + + Silkworm_Cloth** cloths; + uint32_t clothCount; + + uint64_t* nodeIndicesToDestroy; + uint32_t nodeIndicesToDestroyCount; + + uint64_t* linkIndicesToDestroy; + uint32_t linkIndicesToDestroyCount; + + uint64_t* nodeIndexStack; + uint32_t nodeIndexStackCount; + + uint64_t* linkIndexStack; + uint32_t linkIndexStackCount; + + float gravity; + float xBound; + float yBound; + uint32_t clothDensity; + + uint8_t* currentBufferAddress; /* GM doesnt let you pass more than 4 arguments with different types lol */ } Silkworm_Context; static Silkworm_Context *context = NULL; @@ -42,155 +76,485 @@ void Silkworm_Init() { context = malloc(sizeof(Silkworm_Context)); - context->groups = NULL; - context->groupCount = 0; + context->nodes = NULL; + context->nodeCount = 0; + context->links = NULL; + 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->clothCount = 0; + + context->gravity = 200; + context->xBound = 1000; + context->yBound = 1000; + context->clothDensity = 4; } -void Silkworm_Update() +void Silkworm_Update(double deltaTime) { - int32_t i, j, iteration; - Silkworm_Group *group; + uint32_t i, j; Silkworm_Link *link; + Silkworm_Node *node; - for (iteration = 0; iteration < CONSTRAINT_ITERATION_COUNT; iteration += 1) + float delta = (float)deltaTime; + + for (i = 0; i < CONSTRAINT_ITERATION_COUNT; i += 1) { - for (i = 0; i < context->groupCount; i += 1) + for (j = 0; j < context->linkCount; j += 1) { - group = context->groups[i]; + link = context->links[j]; - for (j = 0; j < group->linkCount; j += 1) + if (link != NULL) { - link = group->links[j]; + float diffX = link->a->position.x - link->b->position.x; + float diffY = link->a->position.y - link->b->position.y; + float d = (float)sqrt(diffX * diffX + diffY * diffY); - double diffX = link->a->position.x - link->b->position.y; - double diffY = link->a->position.y - link->b->position.y; - double d = sqrt(diffX * diffX + diffY * diffY); + float difference = (link->distance - d) / d; - double difference = (link->distance - d) / d; + float translateX = diffX * 0.5f * difference; + float translateY = diffY * 0.5f * difference; + + float distanceMoved = (float)sqrt(translateX * translateX + translateY * translateY); - double translateX = diffX * 0.5 * difference; - double translateY = diffY * 0.5 * difference; + if (distanceMoved > link->tearThreshold) + { + context->linkIndicesToDestroy = realloc(context->linkIndicesToDestroy, sizeof(uint64_t) * (context->linkIndicesToDestroyCount + 1)); + context->linkIndicesToDestroy[context->linkIndicesToDestroyCount] = link->id; + context->linkIndicesToDestroyCount += 1; + } + else + { + if (!link->a->pinned) + { + link->a->position.x += translateX; + link->a->position.y += translateY; + } - double distanceMoved = sqrt(translateX * translateX + translateY * translateY); + if (!link->b->pinned) + { + link->b->position.x -= translateX; + link->b->position.y -= translateY; + } + } + } + } + + } + for (j = 0; j < context->nodeCount; j += 1) + { + node = context->nodes[j]; + + if (node != NULL) + { + if (!node->pinned) + { + float velocityX = (node->position.x - node->previousPosition.x) * node->friction; + float velocityY = (node->position.y - node->previousPosition.y) * node->friction; + + float accelerationX = node->acceleration.x * delta * delta; + float accelerationY = (node->acceleration.y + node->mass * context->gravity) * delta * delta; + + node->previousPosition.x = node->position.x; + node->previousPosition.y = node->position.y; + + node->position.x += velocityX + accelerationX; + node->position.y += velocityY + accelerationY; + + node->velocity.x = velocityX * delta; + node->velocity.y = velocityY * delta; + + if (fabs(node->position.x) > context->xBound || fabs(node->position.x) > context->yBound) + { + context->nodeIndicesToDestroy = realloc(context->nodeIndicesToDestroy, sizeof(uint64_t) * (context->nodeIndicesToDestroyCount + 1)); + context->nodeIndicesToDestroy[context->nodeIndicesToDestroyCount] = node->id; + context->nodeIndicesToDestroyCount += 1; + } } } } + + for (j = 0; j < context->nodeIndicesToDestroyCount; j += 1) + { + 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; } -double Silkworm_CreateGroup() +static inline Silkworm_Node* LookupNode(double nodeId) { - context->groups = realloc(context->groups, sizeof(Silkworm_Group*) * (context->groupCount + 1)); - - Silkworm_Group* group = malloc(sizeof(Silkworm_Group)); - - group->nodes = NULL; - group->nodeCount = 0; - group->links = NULL; - group->linkCount = 0; - - context->groups[context->groupCount] = group; - context->groupCount += 1; - - group->id.i = context->groupCount; - - return group->id.d; + return context->nodes[(uint64_t)nodeId]; } -static inline Silkworm_Group* LookupGroup(double groupId) +static inline Silkworm_Cloth* LookupCloth(double clothId) { - Silkworm_ID gId; - gId.d = groupId; - - return context->groups[gId.i]; + return context->cloths[(uint64_t)clothId]; } -static inline Silkworm_Node* LookupNode(double groupId, double nodeId) +double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor) { - Silkworm_ID nId; - nId.d = nodeId; + Silkworm_Node* node = malloc(sizeof(Silkworm_Node)); + uint64_t id; - return LookupGroup(groupId)->nodes[nId.i]; -} + if (context->nodeIndexStackCount > 0) + { + id = context->nodeIndexStack[context->nodeIndexStackCount - 1]; + context->nodeIndexStack = realloc(context->nodeIndexStack, sizeof(uint64_t) * (context->nodeIndexStackCount - 1)); + context->nodeIndexStackCount -= 1; -double Silkworm_CreateNode(double groupId, double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor) -{ - Silkworm_Group *group = LookupGroup(groupId); + context->nodes[id] = node; + } + else + { + id = context->nodeCount; - Silkworm_ID nodeId; - nodeId.i = group->nodeCount; + context->nodes = realloc(context->nodes, sizeof(Silkworm_Node*) * (context->nodeCount + 1)); + context->nodes[context->nodeCount] = node; + context->nodeCount += 1; + } - Silkworm_Node *node = malloc(sizeof(Silkworm_Node)); - node->id = nodeId; - node->position.x = xPosition; - node->position.y = yPosition; - node->previousPosition.x = xPosition; - node->previousPosition.y = yPosition; + node->id = id; + node->position.x = (float)xPosition; + node->position.y = (float)yPosition; + node->previousPosition.x = (float)xPosition; + node->previousPosition.y = (float)yPosition; node->velocity.x = 0; node->velocity.y = 0; node->acceleration.x = 0; node->acceleration.y = 0; - node->mass = mass; - node->friction = friction; - node->radius = radius; - node->pushFactor = pushFactor; + node->mass = (float)mass; + node->friction = (float)friction; + node->radius = (float)radius; + node->pushFactor = (float)pushFactor; node->pinned = false; node->destroyable = false; - group->nodes = realloc(group->nodes, sizeof(Silkworm_Node*) * (group->nodeCount + 1)); - group->nodes[group->nodeCount] = node; - group->nodeCount += 1; - - return nodeId.d; + return (double)node->id; } -void Silkworm_NodeSetVelocity(double groupId, double nodeId, double xVelocity, double yVelocity) +void Silkworm_NodeSetVelocity(double nodeId, double xVelocity, double yVelocity) { - LookupNode(groupId, nodeId)->velocity.x = xVelocity; - LookupNode(groupId, nodeId)->velocity.y = yVelocity; + LookupNode(nodeId)->velocity.x = (float)xVelocity; + LookupNode(nodeId)->velocity.y = (float)yVelocity; } -void Silkworm_NodeSetAcceleration(double groupId, double nodeId, double xAcceleration, double yAcceleration) +void Silkworm_NodeSetAcceleration(double nodeId, double xAcceleration, double yAcceleration) { - LookupNode(groupId, nodeId)->acceleration.x = xAcceleration; - LookupNode(groupId, nodeId)->acceleration.y = yAcceleration; + LookupNode(nodeId)->acceleration.x = (float)xAcceleration; + LookupNode(nodeId)->acceleration.y = (float)yAcceleration; } -void Silkworm_NodeSetDestroyable(double groupId, double nodeId) +void Silkworm_NodeSetDestroyable(double nodeId) { - LookupNode(groupId, nodeId)->destroyable = true; + LookupNode(nodeId)->destroyable = true; } -void Silkworm_NodePin(double groupId, double nodeId) +void Silkworm_NodePin(double nodeId) { - LookupNode(groupId, nodeId)->pinned = true; + LookupNode(nodeId)->pinned = true; } -void Silkworm_NodeUnpin(double groupId, double nodeId) +void Silkworm_NodeUnpin(double nodeId) { - LookupNode(groupId, nodeId)->pinned = false; + LookupNode(nodeId)->pinned = false; } -double Silkworm_CreateLink(double groupId, double aId, double bId, double distance, double tearThreshold) +double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold) { - Silkworm_Group *group = LookupGroup(groupId); + Silkworm_Node *nodeA = LookupNode(aId); + Silkworm_Node *nodeB = LookupNode(bId); - Silkworm_Node *nodeA = LookupNode(groupId, aId); - Silkworm_Node *nodeB = LookupNode(groupId, bId); + uint64_t id; - Silkworm_ID linkId; - linkId.i = group->linkCount; + Silkworm_Link* link = malloc(sizeof(Silkworm_Link)); - Silkworm_Link *link = malloc(sizeof(Silkworm_Link)); - link->id = linkId; + if (context->linkIndexStackCount > 0) + { + id = context->linkIndexStack[context->linkIndexStackCount - 1]; + context->linkIndexStack = realloc(context->linkIndexStack, sizeof(uint64_t) * (context->linkIndexStackCount - 1)); + context->linkIndexStackCount -= 1; + + context->links[id] = link; + } + else + { + id = context->linkCount; + + context->links = realloc(context->links, sizeof(Silkworm_Link*) * (context->linkCount + 1)); + context->links[context->linkCount] = link; + context->linkCount += 1; + } + + link->id = id; link->a = nodeA; link->b = nodeB; - link->distance = distance; - link->tearThreshold = tearThreshold; + link->distance = (float)distance; + link->tearThreshold = (float)tearThreshold; - group->links = realloc(group->links, sizeof(Silkworm_Link*) * (group->linkCount + 1)); - group->links[group->linkCount] = link; - group->linkCount += 1; - - return linkId.d; + return (double)link->id; +} + +double Silkworm_CreateCloth(double xPosition, double yPosition, double horizontalNodeCount, double verticalNodeCount, double mass, double friction, double windFactor, double tearThreshold) +{ + int32_t i, j; + + Silkworm_Cloth* cloth = malloc(sizeof(Silkworm_Cloth)); + + cloth->windFactor = (float)windFactor; + cloth->horizontalNodeCount = (uint32_t) horizontalNodeCount; + cloth->verticalNodeCount = (uint32_t) verticalNodeCount; + cloth->nodeIndices = malloc(sizeof(uint64_t*) * cloth->horizontalNodeCount); + + for (i = 0; i < horizontalNodeCount; i += 1) + { + cloth->nodeIndices[i] = malloc(sizeof(uint64_t) * cloth->verticalNodeCount); + + for (j = 0; j < verticalNodeCount; j += 1) + { + uint64_t id = (uint64_t) Silkworm_CreateNode(xPosition + i * context->clothDensity, yPosition + j * context->clothDensity, mass, friction, 1, 0.5); + + if (j == 0) + { + Silkworm_NodePin((double)id); + } + + Silkworm_NodeSetDestroyable((double)id); + + cloth->nodeIndices[i][j] = id; + } + } + + cloth->triangles = malloc(sizeof(Silkworm_Triangle*) * cloth->horizontalNodeCount * cloth->verticalNodeCount * 2); + uint32_t triangleIndex = 0; + + for (i = 0; i < horizontalNodeCount; i += 1) + { + for (j = 0; j < verticalNodeCount; j += 1) + { + if (i + 1 < horizontalNodeCount && j + 1 < verticalNodeCount) + { + cloth->triangles[triangleIndex] = malloc(sizeof(Silkworm_Triangle)); + + cloth->triangles[triangleIndex]->a = context->nodes[cloth->nodeIndices[i][j]]; + cloth->triangles[triangleIndex]->b = context->nodes[cloth->nodeIndices[i + 1][j]]; + cloth->triangles[triangleIndex]->c = context->nodes[cloth->nodeIndices[i][j + 1]]; + cloth->triangles[triangleIndex]->orientation = UpperLeft; + + cloth->triangles[triangleIndex]->aHorizontalIndex = i; + cloth->triangles[triangleIndex]->aVerticalIndex = j; + + cloth->triangles[triangleIndex]->bHorizontalIndex = i + 1; + cloth->triangles[triangleIndex]->bVerticalIndex = j; + + cloth->triangles[triangleIndex]->cHorizontalIndex = i; + cloth->triangles[triangleIndex]->cVerticalIndex = j + 1; + + triangleIndex += 1; + } + + if (i - 1 >= 0 && j - 1 >= 0) + { + cloth->triangles[triangleIndex] = malloc(sizeof(Silkworm_Triangle)); + + cloth->triangles[triangleIndex]->a = context->nodes[cloth->nodeIndices[i][j]]; + cloth->triangles[triangleIndex]->b = context->nodes[cloth->nodeIndices[i - 1][j]]; + cloth->triangles[triangleIndex]->c = context->nodes[cloth->nodeIndices[i][j - 1]]; + cloth->triangles[triangleIndex]->orientation = BottomRight; + + cloth->triangles[triangleIndex]->aHorizontalIndex = i; + cloth->triangles[triangleIndex]->aVerticalIndex = j; + + cloth->triangles[triangleIndex]->bHorizontalIndex = i - 1; + cloth->triangles[triangleIndex]->bVerticalIndex = j; + + cloth->triangles[triangleIndex]->cHorizontalIndex = i; + cloth->triangles[triangleIndex]->cVerticalIndex = j - 1; + + triangleIndex += 1; + } + } + } + + cloth->triangleCount = triangleIndex; + + for (i = 0; i < horizontalNodeCount; i += 1) + { + for (j = 0; j < verticalNodeCount; j += 1) + { + if (i - 1 >= 0) + { + Silkworm_CreateLink((double)cloth->nodeIndices[i - 1][j], (double)cloth->nodeIndices[i][j], context->clothDensity, tearThreshold); + } + + if (j - 1 >= 0) + { + Silkworm_CreateLink((double)cloth->nodeIndices[i][j - 1], (double)cloth->nodeIndices[i][j], context->clothDensity, tearThreshold); + } + } + } + + uint64_t id; + id = context->clothCount; + + cloth->id = id; + context->cloths = realloc(context->cloths, sizeof(Silkworm_Cloth*) * (context->clothCount + 1)); + context->cloths[context->clothCount] = cloth; + context->clothCount += 1; + + return (double)cloth->id; +} + +void Silkworm_SetTriangleBuffer(const char* bufferId) +{ + context->currentBufferAddress = (uint8_t*)bufferId; +} + +/* pattern is x, y position then color + alpha then UV position */ +double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double widthUV, double topUV, double heightUV) +{ + uint32_t i, triangleCount; + uint8_t* bufferAddress = context->currentBufferAddress; + Silkworm_Cloth* cloth = LookupCloth(clothId); + + Silkworm_Color color; + color.r = 255; + color.g = 255; + color.b = 255; + color.a = 255; + + triangleCount = 0; + for (i = 0; i < cloth->triangleCount; i += 1) + { + if (cloth->triangles[i] != NULL) + { + if (cloth->triangles[i]->orientation == UpperLeft) + { + float left = (float)leftUV + (float)widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1)); + float right = (float)leftUV + (float)widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1)); + + float top = (float)topUV + (float)heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1)); + float bottom = (float)topUV + (float)heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1)); + + memcpy(bufferAddress, &cloth->triangles[i]->a->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &left, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &top, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &cloth->triangles[i]->b->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &right, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &top, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &cloth->triangles[i]->c->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &left, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &bottom, sizeof(float)); + bufferAddress += sizeof(float); + + triangleCount += 1; + } + else if (cloth->triangles[i]->orientation == BottomRight) + { + float left = (float)leftUV + (float)widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1)); + float right = (float)leftUV + (float)widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1)); + + float top = (float)topUV + (float)heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1)); + float bottom = (float)topUV + (float)heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1)); + + memcpy(bufferAddress, &cloth->triangles[i]->a->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &right, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &bottom, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &cloth->triangles[i]->b->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &left, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &bottom, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &cloth->triangles[i]->c->position, sizeof(Silkworm_Vector2)); + bufferAddress += sizeof(Silkworm_Vector2); + + memcpy(bufferAddress, &color, sizeof(Silkworm_Color)); + bufferAddress += sizeof(Silkworm_Color); + + memcpy(bufferAddress, &right, sizeof(float)); + bufferAddress += sizeof(float); + + memcpy(bufferAddress, &top, sizeof(float)); + bufferAddress += sizeof(float); + + triangleCount += 1; + } + } + } + + return (double)triangleCount; } diff --git a/src/Silkworm.h b/src/Silkworm.h index ca830d5..92590bb 100644 --- a/src/Silkworm.h +++ b/src/Silkworm.h @@ -43,51 +43,80 @@ extern "C" { #endif /* __cplusplus */ -/* Game Maker only lets us use doubles in the API. So we do type punning to get integers. It's legal in C99! */ -typedef union { - int i; - double d; -} Silkworm_ID; - typedef struct Silkworm_Vector2 { - double x; - double y; + float x; + float y; } Silkworm_Vector2; typedef struct Silkworm_Node { - Silkworm_ID id; + uint64_t id; Silkworm_Vector2 position; Silkworm_Vector2 previousPosition; Silkworm_Vector2 velocity; Silkworm_Vector2 acceleration; - double mass; - double friction; - double radius; - double pinned; - double pushFactor; + float mass; + float friction; + float radius; + float pinned; + float pushFactor; bool destroyable; } Silkworm_Node; typedef struct Silkworm_Link { - Silkworm_ID id; + uint64_t id; Silkworm_Node *a; Silkworm_Node *b; - double distance; - double tearThreshold; + float distance; + float tearThreshold; } Silkworm_Link; -typedef struct Silkworm_Group +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 { - Silkworm_ID id; - Silkworm_Node **nodes; uint32_t nodeCount; - Silkworm_Link **links; - uint32_t linkCount; -} Silkworm_Group; + uint32_t *nodeIndices; +} Silkworm_Rope; /* Version API */ @@ -103,19 +132,19 @@ typedef struct Silkworm_Group ) SILKWORMAPI void Silkworm_Init(); -SILKWORMAPI void Silkworm_Update(); +SILKWORMAPI void Silkworm_Update(double delta); -SILKWORMAPI double Silkworm_CreateGroup(); +SILKWORMAPI double Silkworm_CreateNode(double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor); -SILKWORMAPI double Silkworm_CreateNode(double groupId, double xPosition, double yPosition, double mass, double friction, double radius, double pushFactor); +SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId); +SILKWORMAPI void Silkworm_NodePin(double nodeId); +SILKWORMAPI void Silkworm_NodeUnpin(double nodeId); -SILKWORMAPI void Silkworm_NodeSetVelocity(double groupId, double nodeId, double xVelocity, double yVelocity); -SILKWORMAPI void Silkworm_NodeSetAcceleration(double groupId, double nodeId, double xAcceleration, double yAcceleration); +SILKWORMAPI double Silkworm_CreateLink(double aId, double bId, double distance, double tearThreshold); -SILKWORMAPI void Silkworm_NodeSetDestroyable(double groupId, double nodeId); -SILKWORMAPI void Silkworm_NodePin(double groupId, double nodeId); -SILKWORMAPI void Silkworm_NodeUnpin(double groupId, double nodeId); +SILKWORMAPI double Silkworm_CreateCloth(double xPosition, double yPosition, double horizontalNodeCount, double verticalNodeCount, double mass, double friction, double windFactor, double tearThreshold); -SILKWORMAPI double Silkworm_CreateLink(double groupId, double aId, double bId, double distance, double tearThreshold); +SILKWORMAPI void Silkworm_SetTriangleBuffer(const char* bufferId); +SILKWORMAPI double Silkworm_ClothFillTriangleBuffer(double clothId, double leftUV, double widthUV, double topUV, double heightUV); #endif /* SILKWORM_H */ diff --git a/visualc/Silkworm.vcxproj b/visualc/Silkworm.vcxproj index 014ab6d..94b617c 100644 --- a/visualc/Silkworm.vcxproj +++ b/visualc/Silkworm.vcxproj @@ -21,7 +21,7 @@ {6DB15344-E000-45CB-A48A-1D72F7D6E945} Silkworm - 10.0.16299.0 + 10.0 @@ -36,16 +36,16 @@ MultiByte - v141 + v142 - v141 + v142 - v141 + v142 - v141 + v142