some API improvements
parent
bad2d6b00b
commit
18b84ca0c4
167
src/Silkworm2.c
167
src/Silkworm2.c
|
@ -294,6 +294,13 @@ typedef struct Silkworm_Cloth
|
||||||
uint32_t horizontalNodeCount;
|
uint32_t horizontalNodeCount;
|
||||||
uint32_t verticalNodeCount;
|
uint32_t verticalNodeCount;
|
||||||
|
|
||||||
|
float depth;
|
||||||
|
|
||||||
|
float leftUV;
|
||||||
|
float widthUV;
|
||||||
|
float topUV;
|
||||||
|
float heightUV;
|
||||||
|
|
||||||
/* note that the cloth doesn't own the nodes, just has pointers to them */
|
/* note that the cloth doesn't own the nodes, just has pointers to them */
|
||||||
Silkworm_Node*** nodes; /* x by y grid of indices */
|
Silkworm_Node*** nodes; /* x by y grid of indices */
|
||||||
|
|
||||||
|
@ -350,6 +357,9 @@ typedef struct Silkworm_Context
|
||||||
Silkworm_Vector2* linkDestructionData;
|
Silkworm_Vector2* linkDestructionData;
|
||||||
uint32_t linkDestructionDataCount;
|
uint32_t linkDestructionDataCount;
|
||||||
uint32_t linkDestructionDataCapacity;
|
uint32_t linkDestructionDataCapacity;
|
||||||
|
|
||||||
|
Silkworm_Vertex* vertexBuffer;
|
||||||
|
uint32_t vertexCapacity;
|
||||||
} Silkworm_Context;
|
} Silkworm_Context;
|
||||||
|
|
||||||
static Silkworm_Context *context = NULL;
|
static Silkworm_Context *context = NULL;
|
||||||
|
@ -394,6 +404,9 @@ void Silkworm_Init()
|
||||||
context->linkDestructionDataCapacity = 16;
|
context->linkDestructionDataCapacity = 16;
|
||||||
context->linkDestructionData = malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity);
|
context->linkDestructionData = malloc(sizeof(Silkworm_Vector2) * context->nodeDestructionDataCapacity);
|
||||||
context->linkDestructionDataCount = 0;
|
context->linkDestructionDataCount = 0;
|
||||||
|
|
||||||
|
context->vertexCapacity = 1024;
|
||||||
|
context->vertexBuffer = malloc(sizeof(Silkworm_Vertex) * context->vertexCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Silkworm_Node* LookupNode(uint64_t nodeId)
|
static inline Silkworm_Node* LookupNode(uint64_t nodeId)
|
||||||
|
@ -640,6 +653,22 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY)
|
||||||
context->nodeDestructionDataCount = 0;
|
context->nodeDestructionDataCount = 0;
|
||||||
context->linkDestructionDataCount = 0;
|
context->linkDestructionDataCount = 0;
|
||||||
|
|
||||||
|
// apply wind
|
||||||
|
for (i = 0; i < context->nodeCount; i += 1)
|
||||||
|
{
|
||||||
|
node = context->nodes[i];
|
||||||
|
|
||||||
|
if (node != NULL)
|
||||||
|
{
|
||||||
|
if (!node->pinned)
|
||||||
|
{
|
||||||
|
node->position.x += (0.5f * sinf(context->timeElapsed * 4 + node->position.y / 2) + 0.5f) * windSpeedX * delta * 0.05f * node->windFactor;
|
||||||
|
node->position.y += (0.5f * sinf(context->timeElapsed * 4 + node->position.x / 3) + 0.5f) * windSpeedY * delta * 0.05f * node->windFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// solve constraints
|
||||||
for (i = 0; i < CONSTRAINT_ITERATION_COUNT; i += 1)
|
for (i = 0; i < CONSTRAINT_ITERATION_COUNT; i += 1)
|
||||||
{
|
{
|
||||||
for (j = 0; j < context->linkCount; j += 1)
|
for (j = 0; j < context->linkCount; j += 1)
|
||||||
|
@ -657,9 +686,9 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY)
|
||||||
float translateX = diffX * 0.5f * difference;
|
float translateX = diffX * 0.5f * difference;
|
||||||
float translateY = diffY * 0.5f * difference;
|
float translateY = diffY * 0.5f * difference;
|
||||||
|
|
||||||
float distanceMoved = (float)sqrt(translateX * translateX + translateY * translateY);
|
float distanceMovedSquared = translateX * translateX + translateY * translateY;
|
||||||
|
|
||||||
if (distanceMoved > link->tearThreshold)
|
if (distanceMovedSquared > link->tearThreshold * link->tearThreshold)
|
||||||
{
|
{
|
||||||
Silkworm_DestroyLink((double)link->id);
|
Silkworm_DestroyLink((double)link->id);
|
||||||
}
|
}
|
||||||
|
@ -681,6 +710,7 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update node positions
|
||||||
for (j = 0; j < context->nodeCount; j += 1)
|
for (j = 0; j < context->nodeCount; j += 1)
|
||||||
{
|
{
|
||||||
node = context->nodes[j];
|
node = context->nodes[j];
|
||||||
|
@ -701,9 +731,6 @@ void Silkworm_Update(float delta, float windSpeedX, float windSpeedY)
|
||||||
node->position.x += velocityX + accelerationX;
|
node->position.x += velocityX + accelerationX;
|
||||||
node->position.y += velocityY + accelerationY;
|
node->position.y += velocityY + accelerationY;
|
||||||
|
|
||||||
node->position.x += (0.5f * sinf(context->timeElapsed * 4 + node->position.y / 2) + 0.5f) * windSpeedX * 0.05f * node->windFactor;
|
|
||||||
node->position.y += (0.5f * sinf(context->timeElapsed * 4 + node->position.x / 3) + 0.5f) * windSpeedY * 0.05f * node->windFactor;
|
|
||||||
|
|
||||||
node->velocity.x = velocityX * delta;
|
node->velocity.x = velocityX * delta;
|
||||||
node->velocity.y = velocityY * delta;
|
node->velocity.y = velocityY * delta;
|
||||||
|
|
||||||
|
@ -842,8 +869,9 @@ void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo)
|
||||||
|
|
||||||
Silkworm_Cloth* cloth = malloc(sizeof(Silkworm_Cloth));
|
Silkworm_Cloth* cloth = malloc(sizeof(Silkworm_Cloth));
|
||||||
|
|
||||||
cloth->horizontalNodeCount = ((uint32_t)clothCreateInfo->horizontalNodeCount / context->clothDensity) + 1;
|
cloth->horizontalNodeCount = (uint32_t)clothCreateInfo->horizontalNodeCount;
|
||||||
cloth->verticalNodeCount = ((uint32_t)clothCreateInfo->verticalNodeCount / context->clothDensity) + 1;
|
cloth->verticalNodeCount = (uint32_t)clothCreateInfo->verticalNodeCount;
|
||||||
|
|
||||||
cloth->nodes = malloc(sizeof(Silkworm_Node**) * cloth->horizontalNodeCount);
|
cloth->nodes = malloc(sizeof(Silkworm_Node**) * cloth->horizontalNodeCount);
|
||||||
|
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
|
@ -898,11 +926,6 @@ void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo)
|
||||||
|
|
||||||
cloth->nodes[i][j] = node;
|
cloth->nodes[i][j] = node;
|
||||||
|
|
||||||
if (j == 0)
|
|
||||||
{
|
|
||||||
node->pinned = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->destroyable = true;
|
node->destroyable = true;
|
||||||
|
|
||||||
node->clothReference.clothId = cloth->id;
|
node->clothReference.clothId = cloth->id;
|
||||||
|
@ -1024,89 +1047,101 @@ void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloth->depth = clothCreateInfo->z;
|
||||||
|
|
||||||
|
cloth->leftUV = clothCreateInfo->leftUV;
|
||||||
|
cloth->widthUV = clothCreateInfo->rightUV - clothCreateInfo->leftUV;
|
||||||
|
cloth->topUV = clothCreateInfo->topUV;
|
||||||
|
cloth->heightUV = clothCreateInfo->bottomUV - clothCreateInfo->topUV;
|
||||||
|
|
||||||
return (void*) cloth;
|
return (void*) cloth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: this is very unsafe */
|
uint32_t Silkworm_ClothRender(void **pVertexBuffer, uint32_t *pVertexBufferLengthInBytes)
|
||||||
double Silkworm_ClothHorizontalNodeCount(double clothId)
|
|
||||||
{
|
{
|
||||||
return context->cloths[(uint32_t)clothId]->horizontalNodeCount;
|
uint32_t i, j, vertexCount;
|
||||||
}
|
|
||||||
|
|
||||||
double Silkworm_ClothVerticalNodeCount(double clothId)
|
|
||||||
{
|
|
||||||
return context->cloths[(uint32_t)clothId]->verticalNodeCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t Silkworm_ClothFillTriangleBuffer(void* clothPtr, void* vertexBufferPtr, float depth, float leftUV, float widthUV, float topUV, float heightUV)
|
|
||||||
{
|
|
||||||
uint32_t i, vertexCount;
|
|
||||||
Silkworm_Cloth* cloth = (Silkworm_Cloth*) clothPtr;
|
|
||||||
Silkworm_Vertex* vertexBuffer = (Silkworm_Vertex*) vertexBufferPtr;
|
|
||||||
|
|
||||||
vertexCount = 0;
|
vertexCount = 0;
|
||||||
|
|
||||||
|
for (j = 0; j < context->clothCount; j += 1)
|
||||||
|
{
|
||||||
|
Silkworm_Cloth* cloth = context->cloths[j];
|
||||||
|
|
||||||
|
if (cloth != NULL)
|
||||||
|
{
|
||||||
|
if (vertexCount + (cloth->triangleCount * 3) > context->vertexCapacity)
|
||||||
|
{
|
||||||
|
context->vertexCapacity *= 2;
|
||||||
|
context->vertexBuffer = realloc(context->vertexBuffer, sizeof(Silkworm_Vertex) * context->vertexCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < cloth->triangleCount; i += 1)
|
for (i = 0; i < cloth->triangleCount; i += 1)
|
||||||
{
|
{
|
||||||
if (cloth->triangles[i] != NULL)
|
if (cloth->triangles[i] != NULL)
|
||||||
{
|
{
|
||||||
if (cloth->triangles[i]->orientation == UpperLeft)
|
if (cloth->triangles[i]->orientation == UpperLeft)
|
||||||
{
|
{
|
||||||
float left = leftUV + widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
float left = cloth->leftUV + cloth->widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
||||||
float right = leftUV + widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
float right = cloth->leftUV + cloth->widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
||||||
|
|
||||||
float top = topUV + heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1));
|
float top = cloth->topUV + cloth->heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1));
|
||||||
float bottom = topUV + heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1));
|
float bottom = cloth->topUV + cloth->heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1));
|
||||||
|
|
||||||
vertexBuffer[vertexCount].x = cloth->triangles[i]->a->position.x;
|
context->vertexBuffer[vertexCount].x = cloth->triangles[i]->a->position.x;
|
||||||
vertexBuffer[vertexCount].y = cloth->triangles[i]->a->position.y;
|
context->vertexBuffer[vertexCount].y = cloth->triangles[i]->a->position.y;
|
||||||
vertexBuffer[vertexCount].z = depth;
|
context->vertexBuffer[vertexCount].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount].u = left;
|
context->vertexBuffer[vertexCount].u = left;
|
||||||
vertexBuffer[vertexCount].v = top;
|
context->vertexBuffer[vertexCount].v = top;
|
||||||
|
|
||||||
vertexBuffer[vertexCount + 1].x = cloth->triangles[i]->b->position.x;
|
context->vertexBuffer[vertexCount + 1].x = cloth->triangles[i]->b->position.x;
|
||||||
vertexBuffer[vertexCount + 1].y = cloth->triangles[i]->b->position.y;
|
context->vertexBuffer[vertexCount + 1].y = cloth->triangles[i]->b->position.y;
|
||||||
vertexBuffer[vertexCount + 1].z = depth;
|
context->vertexBuffer[vertexCount + 1].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount + 1].u = right;
|
context->vertexBuffer[vertexCount + 1].u = right;
|
||||||
vertexBuffer[vertexCount + 1].v = top;
|
context->vertexBuffer[vertexCount + 1].v = top;
|
||||||
|
|
||||||
vertexBuffer[vertexCount + 2].x = cloth->triangles[i]->c->position.x;
|
context->vertexBuffer[vertexCount + 2].x = cloth->triangles[i]->c->position.x;
|
||||||
vertexBuffer[vertexCount + 2].y = cloth->triangles[i]->c->position.y;
|
context->vertexBuffer[vertexCount + 2].y = cloth->triangles[i]->c->position.y;
|
||||||
vertexBuffer[vertexCount + 2].z = depth;
|
context->vertexBuffer[vertexCount + 2].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount + 2].u = left;
|
context->vertexBuffer[vertexCount + 2].u = left;
|
||||||
vertexBuffer[vertexCount + 2].v = bottom;
|
context->vertexBuffer[vertexCount + 2].v = bottom;
|
||||||
|
|
||||||
vertexCount += 3;
|
vertexCount += 3;
|
||||||
}
|
}
|
||||||
else if (cloth->triangles[i]->orientation == BottomRight)
|
else if (cloth->triangles[i]->orientation == BottomRight)
|
||||||
{
|
{
|
||||||
float left = leftUV + widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
float left = cloth->leftUV + cloth->widthUV * ((float)cloth->triangles[i]->bHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
||||||
float right = leftUV + widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
float right = cloth->leftUV + cloth->widthUV * ((float)cloth->triangles[i]->aHorizontalIndex / (cloth->horizontalNodeCount - 1));
|
||||||
|
|
||||||
float top = topUV + heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1));
|
float top = cloth->topUV + cloth->heightUV * ((float)cloth->triangles[i]->cVerticalIndex / (cloth->verticalNodeCount - 1));
|
||||||
float bottom = topUV + heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1));
|
float bottom = cloth->topUV + cloth->heightUV * ((float)cloth->triangles[i]->aVerticalIndex / (cloth->verticalNodeCount - 1));
|
||||||
|
|
||||||
vertexBuffer[vertexCount].x = cloth->triangles[i]->a->position.x;
|
context->vertexBuffer[vertexCount].x = cloth->triangles[i]->a->position.x;
|
||||||
vertexBuffer[vertexCount].y = cloth->triangles[i]->a->position.y;
|
context->vertexBuffer[vertexCount].y = cloth->triangles[i]->a->position.y;
|
||||||
vertexBuffer[vertexCount].z = depth;
|
context->vertexBuffer[vertexCount].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount].u = right;
|
context->vertexBuffer[vertexCount].u = right;
|
||||||
vertexBuffer[vertexCount].v = bottom;
|
context->vertexBuffer[vertexCount].v = bottom;
|
||||||
|
|
||||||
vertexBuffer[vertexCount + 1].x = cloth->triangles[i]->b->position.x;
|
context->vertexBuffer[vertexCount + 1].x = cloth->triangles[i]->b->position.x;
|
||||||
vertexBuffer[vertexCount + 1].y = cloth->triangles[i]->b->position.y;
|
context->vertexBuffer[vertexCount + 1].y = cloth->triangles[i]->b->position.y;
|
||||||
vertexBuffer[vertexCount + 1].z = depth;
|
context->vertexBuffer[vertexCount + 1].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount + 1].u = left;
|
context->vertexBuffer[vertexCount + 1].u = left;
|
||||||
vertexBuffer[vertexCount + 1].v = bottom;
|
context->vertexBuffer[vertexCount + 1].v = bottom;
|
||||||
|
|
||||||
vertexBuffer[vertexCount + 2].x = cloth->triangles[i]->c->position.x;
|
context->vertexBuffer[vertexCount + 2].x = cloth->triangles[i]->c->position.x;
|
||||||
vertexBuffer[vertexCount + 2].y = cloth->triangles[i]->c->position.y;
|
context->vertexBuffer[vertexCount + 2].y = cloth->triangles[i]->c->position.y;
|
||||||
vertexBuffer[vertexCount + 2].z = depth;
|
context->vertexBuffer[vertexCount + 2].z = cloth->depth;
|
||||||
vertexBuffer[vertexCount + 2].u = right;
|
context->vertexBuffer[vertexCount + 2].u = right;
|
||||||
vertexBuffer[vertexCount + 2].v = top;
|
context->vertexBuffer[vertexCount + 2].v = top;
|
||||||
|
|
||||||
vertexCount += 3;
|
vertexCount += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*pVertexBuffer = context->vertexBuffer;
|
||||||
|
*pVertexBufferLengthInBytes = sizeof(Silkworm_Vertex) * vertexCount;
|
||||||
|
}
|
||||||
|
|
||||||
return vertexCount;
|
return vertexCount;
|
||||||
}
|
}
|
||||||
|
@ -1288,6 +1323,8 @@ void Silkworm_Finish()
|
||||||
free(context->nodeDestructionData);
|
free(context->nodeDestructionData);
|
||||||
free(context->linkDestructionData);
|
free(context->linkDestructionData);
|
||||||
|
|
||||||
|
free(context->vertexBuffer);
|
||||||
|
|
||||||
free(context);
|
free(context);
|
||||||
context = NULL;
|
context = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,8 +58,8 @@ extern "C" {
|
||||||
|
|
||||||
typedef struct Silkworm_NodeCreateInfo
|
typedef struct Silkworm_NodeCreateInfo
|
||||||
{
|
{
|
||||||
int32_t x;
|
float x;
|
||||||
int32_t y;
|
float y;
|
||||||
float mass;
|
float mass;
|
||||||
float friction;
|
float friction;
|
||||||
float radius;
|
float radius;
|
||||||
|
@ -71,14 +71,19 @@ typedef struct Silkworm_NodeCreateInfo
|
||||||
|
|
||||||
typedef struct Silkworm_ClothCreateInfo
|
typedef struct Silkworm_ClothCreateInfo
|
||||||
{
|
{
|
||||||
int32_t x;
|
float x;
|
||||||
int32_t y;
|
float y;
|
||||||
|
float z;
|
||||||
int32_t horizontalNodeCount;
|
int32_t horizontalNodeCount;
|
||||||
int32_t verticalNodeCount;
|
int32_t verticalNodeCount;
|
||||||
float mass;
|
float mass;
|
||||||
float friction;
|
float friction;
|
||||||
float windFactor;
|
float windFactor;
|
||||||
float tearThreshold;
|
float tearThreshold;
|
||||||
|
float leftUV;
|
||||||
|
float topUV;
|
||||||
|
float rightUV;
|
||||||
|
float bottomUV;
|
||||||
} Silkworm_ClothCreateInfo;
|
} Silkworm_ClothCreateInfo;
|
||||||
|
|
||||||
typedef struct Silkworm_Vertex
|
typedef struct Silkworm_Vertex
|
||||||
|
@ -102,7 +107,7 @@ SILKWORMAPI void* Silkworm_ClothCreate(Silkworm_ClothCreateInfo* clothCreateInfo
|
||||||
SILKWORMAPI void Silkworm_ClothNodePin(void* clothPtr, uint32_t i, uint32_t j);
|
SILKWORMAPI void Silkworm_ClothNodePin(void* clothPtr, uint32_t i, uint32_t j);
|
||||||
SILKWORMAPI void Silkworm_ClothNodeUnpin(void* clothPtr, uint32_t i, uint32_t j);
|
SILKWORMAPI void Silkworm_ClothNodeUnpin(void* clothPtr, uint32_t i, uint32_t j);
|
||||||
SILKWORMAPI void Silkworm_ClothNodeDestroy(void* clothPtr, uint32_t i, uint32_t j);
|
SILKWORMAPI void Silkworm_ClothNodeDestroy(void* clothPtr, uint32_t i, uint32_t j);
|
||||||
SILKWORMAPI int32_t Silkworm_ClothFillTriangleBuffer(void* clothPtr, void* vertexBufferPtr, float depth, float leftUV, float widthUV, float topUV, float heightUV);
|
SILKWORMAPI uint32_t Silkworm_ClothRender(void **pVertexBuffer, uint32_t *pVertexBufferLengthInBytes);
|
||||||
SILKWORMAPI void Silkworm_ClothDestroy(void* clothPtr);
|
SILKWORMAPI void Silkworm_ClothDestroy(void* clothPtr);
|
||||||
|
|
||||||
SILKWORMAPI void Silkworm_PinNodesInRadius(float x, float y, float radius);
|
SILKWORMAPI void Silkworm_PinNodesInRadius(float x, float y, float radius);
|
||||||
|
|
Loading…
Reference in New Issue