more features
parent
95c89d3ce1
commit
26516c9829
196
src/Silkworm.c
196
src/Silkworm.c
|
@ -47,7 +47,7 @@ typedef struct Silkworm_Node
|
||||||
float mass;
|
float mass;
|
||||||
float friction;
|
float friction;
|
||||||
float radius;
|
float radius;
|
||||||
float pinned;
|
bool pinned;
|
||||||
float pushFactor;
|
float pushFactor;
|
||||||
bool destroyable;
|
bool destroyable;
|
||||||
|
|
||||||
|
@ -413,7 +413,10 @@ void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
|
||||||
{
|
{
|
||||||
free(cloth->nodeHash.buckets[i].elements[j].indexArray);
|
free(cloth->nodeHash.buckets[i].elements[j].indexArray);
|
||||||
}
|
}
|
||||||
free(cloth->nodeHash.buckets[i].elements);
|
if (cloth->nodeHash.buckets[i].elements != NULL)
|
||||||
|
{
|
||||||
|
free(cloth->nodeHash.buckets[i].elements);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NUM_LINK_TRIANGLE_HASH_BUCKETS; i += 1)
|
for (i = 0; i < NUM_LINK_TRIANGLE_HASH_BUCKETS; i += 1)
|
||||||
|
@ -422,7 +425,10 @@ void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
|
||||||
{
|
{
|
||||||
free(cloth->linkHash.buckets[i].elements[j].indexArray);
|
free(cloth->linkHash.buckets[i].elements[j].indexArray);
|
||||||
}
|
}
|
||||||
free(cloth->linkHash.buckets[i].elements);
|
if (cloth->linkHash.buckets[i].elements != NULL)
|
||||||
|
{
|
||||||
|
free(cloth->linkHash.buckets[i].elements);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < cloth->horizontalNodeCount; i += 1)
|
for (i = 0; i < cloth->horizontalNodeCount; i += 1)
|
||||||
|
@ -434,7 +440,15 @@ void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
|
||||||
free(cloth->nodeIndices[i]);
|
free(cloth->nodeIndices[i]);
|
||||||
}
|
}
|
||||||
free(cloth->nodeIndices);
|
free(cloth->nodeIndices);
|
||||||
free(cloth);
|
|
||||||
|
for (i = 0; i < cloth->triangleCount; i += 1)
|
||||||
|
{
|
||||||
|
if (cloth->triangles[i] != NULL)
|
||||||
|
{
|
||||||
|
free(cloth->triangles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(cloth->triangles);
|
||||||
|
|
||||||
if (context->clothIndexStackCount >= context->clothIndexStackCapacity)
|
if (context->clothIndexStackCount >= context->clothIndexStackCapacity)
|
||||||
{
|
{
|
||||||
|
@ -444,6 +458,8 @@ void Silkworm_Internal_DestroyCloth(Silkworm_Cloth* cloth)
|
||||||
|
|
||||||
context->clothIndexStack[context->clothIndexStackCount] = cloth->id;
|
context->clothIndexStack[context->clothIndexStackCount] = cloth->id;
|
||||||
context->clothIndexStackCount += 1;
|
context->clothIndexStackCount += 1;
|
||||||
|
|
||||||
|
free(cloth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Silkworm_DestroyCloth(double clothId)
|
void Silkworm_DestroyCloth(double clothId)
|
||||||
|
@ -940,6 +956,47 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double width, do
|
||||||
return (double)cloth->id;
|
return (double)cloth->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: this is very unsafe */
|
||||||
|
double Silkworm_ClothHorizontalNodeCount(double clothId)
|
||||||
|
{
|
||||||
|
return context->cloths[(uint32_t)clothId]->horizontalNodeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Silkworm_ClothVerticalNodeCount(double clothId)
|
||||||
|
{
|
||||||
|
return context->cloths[(uint32_t)clothId]->verticalNodeCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Silkworm_ClothFillNodeDataBuffer(double clothId)
|
||||||
|
{
|
||||||
|
uint32_t i, j;
|
||||||
|
uint8_t* bufferAddress = context->currentBufferAddress;
|
||||||
|
Silkworm_Cloth* cloth = LookupCloth(clothId);
|
||||||
|
|
||||||
|
uint8_t active = 0;
|
||||||
|
uint8_t pinned = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < cloth->horizontalNodeCount; i += 1)
|
||||||
|
{
|
||||||
|
for (j = 0; j < cloth->verticalNodeCount; j += 1)
|
||||||
|
{
|
||||||
|
active = context->nodes[cloth->nodeIndices[i][j]] != NULL;
|
||||||
|
|
||||||
|
memcpy(bufferAddress, &active, sizeof(uint8_t));
|
||||||
|
bufferAddress += sizeof(uint8_t);
|
||||||
|
|
||||||
|
pinned = 0;
|
||||||
|
if (context->nodes[cloth->nodeIndices[i][j]] != NULL)
|
||||||
|
{
|
||||||
|
pinned = context->nodes[cloth->nodeIndices[i][j]]->pinned;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(bufferAddress, &pinned, sizeof(uint8_t));
|
||||||
|
bufferAddress += sizeof(uint8_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Silkworm_ApplyWind(double xSpeed, double ySpeed)
|
void Silkworm_ApplyWind(double xSpeed, double ySpeed)
|
||||||
{
|
{
|
||||||
uint32_t i, j, k;
|
uint32_t i, j, k;
|
||||||
|
@ -969,7 +1026,7 @@ void Silkworm_ApplyWind(double xSpeed, double ySpeed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Silkworm_SetTriangleBuffer(const char* bufferId)
|
void Silkworm_SetBuffer(const char* bufferId)
|
||||||
{
|
{
|
||||||
context->currentBufferAddress = (uint8_t*)bufferId;
|
context->currentBufferAddress = (uint8_t*)bufferId;
|
||||||
}
|
}
|
||||||
|
@ -1218,6 +1275,19 @@ double Silkworm_FillEditorBuffer()
|
||||||
|
|
||||||
if (node != NULL)
|
if (node != NULL)
|
||||||
{
|
{
|
||||||
|
if (node->pinned)
|
||||||
|
{
|
||||||
|
color.r = 255;
|
||||||
|
color.g = 255;
|
||||||
|
color.b = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color.r = 255;
|
||||||
|
color.g = 0;
|
||||||
|
color.b = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* top left triangle */
|
/* top left triangle */
|
||||||
position.x = node->position.x - node->radius;
|
position.x = node->position.x - node->radius;
|
||||||
position.y = node->position.y - node->radius;
|
position.y = node->position.y - node->radius;
|
||||||
|
@ -1293,7 +1363,7 @@ void Silkworm_PushNodesInRadius(double x, double y, double radius, double xDirec
|
||||||
{
|
{
|
||||||
Silkworm_Node* node = context->nodes[i];
|
Silkworm_Node* node = context->nodes[i];
|
||||||
|
|
||||||
if (node != NULL)
|
if (node != NULL && !node->pinned)
|
||||||
{
|
{
|
||||||
float xDistance = (float)fabs((float)x - node->position.x);
|
float xDistance = (float)fabs((float)x - node->position.x);
|
||||||
float yDistance = (float)fabs((float)y - node->position.y);
|
float yDistance = (float)fabs((float)y - node->position.y);
|
||||||
|
@ -1309,6 +1379,56 @@ void Silkworm_PushNodesInRadius(double x, double y, double radius, double xDirec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Silkworm_PinNodesInRadius(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)
|
||||||
|
{
|
||||||
|
node->pinned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Silkworm_UnpinNodesInRadius(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)
|
||||||
|
{
|
||||||
|
node->pinned = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
|
void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
|
||||||
{
|
{
|
||||||
/* TODO: spatial hash implementation */
|
/* TODO: spatial hash implementation */
|
||||||
|
@ -1332,6 +1452,54 @@ void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Silkworm_PerformDestroys();
|
||||||
|
}
|
||||||
|
|
||||||
|
double Silkworm_DestroyClothInRadius(double x, double y, double radius)
|
||||||
|
{
|
||||||
|
/* TODO: spatial hash implementation */
|
||||||
|
|
||||||
|
uint32_t i, j;
|
||||||
|
double clothId = -1;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
for (j = 0; j < context->clothCount; j += 1)
|
||||||
|
{
|
||||||
|
Silkworm_Cloth* cloth = context->cloths[j];
|
||||||
|
|
||||||
|
if (cloth != NULL)
|
||||||
|
{
|
||||||
|
/* if the node has a triangle in the cloth, it's part of the cloth! */
|
||||||
|
uint32_t arrayCount = 0;
|
||||||
|
NodeTriangleHashTable_Fetch(&cloth->nodeHash, node, &arrayCount);
|
||||||
|
|
||||||
|
if (arrayCount > 0)
|
||||||
|
{
|
||||||
|
clothId = (double)cloth->id;
|
||||||
|
Silkworm_Internal_DestroyCloth(cloth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Silkworm_PerformDestroys();
|
||||||
|
return clothId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Silkworm_ClearAll()
|
void Silkworm_ClearAll()
|
||||||
|
@ -1348,3 +1516,19 @@ void Silkworm_ClearAll()
|
||||||
|
|
||||||
Silkworm_PerformDestroys();
|
Silkworm_PerformDestroys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Silkworm_Finish()
|
||||||
|
{
|
||||||
|
Silkworm_ClearAll();
|
||||||
|
|
||||||
|
free(context->nodes);
|
||||||
|
free(context->links);
|
||||||
|
free(context->cloths);
|
||||||
|
|
||||||
|
free(context->nodeIndexStack);
|
||||||
|
free(context->linkIndexStack);
|
||||||
|
free(context->clothIndexStack);
|
||||||
|
|
||||||
|
free(context);
|
||||||
|
context = NULL;
|
||||||
|
}
|
|
@ -60,19 +60,23 @@ 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 void Silkworm_ApplyWind(double xSpeed, double ySpeed);
|
||||||
|
|
||||||
|
SILKWORMAPI void Silkworm_SetBuffer(const char* bufferId);
|
||||||
|
|
||||||
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 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 width, double height, double mass, double friction, double windFactor, double tearThreshold);
|
||||||
|
SILKWORMAPI double Silkworm_ClothHorizontalNodeCount(double clothId);
|
||||||
|
SILKWORMAPI double Silkworm_ClothVerticalNodeCount(double clothId);
|
||||||
SILKWORMAPI void Silkworm_ClothNodePin(double clothId, double i, double j);
|
SILKWORMAPI void Silkworm_ClothNodePin(double clothId, double i, double j);
|
||||||
SILKWORMAPI void Silkworm_ClothNodeUnpin(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_ClothNodeDestroy(double clothId, double i, double j);
|
||||||
|
SILKWORMAPI void Silkworm_ClothFillNodeDataBuffer(double clothId);
|
||||||
SILKWORMAPI void Silkworm_DestroyCloth(double clothId);
|
SILKWORMAPI void Silkworm_DestroyCloth(double clothId);
|
||||||
|
|
||||||
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 double Silkworm_GetEditorBufferRequiredSize();
|
SILKWORMAPI double Silkworm_GetEditorBufferRequiredSize();
|
||||||
|
@ -80,9 +84,13 @@ SILKWORMAPI double Silkworm_FillEditorBuffer();
|
||||||
|
|
||||||
SILKWORMAPI void Silkworm_DestroyNode(double nodeId);
|
SILKWORMAPI void Silkworm_DestroyNode(double nodeId);
|
||||||
|
|
||||||
|
SILKWORMAPI void Silkworm_PinNodesInRadius(double x, double y, double radius);
|
||||||
|
SILKWORMAPI void Silkworm_UnpinNodesInRadius(double x, double y, double radius);
|
||||||
SILKWORMAPI void Silkworm_PushNodesInRadius(double x, double y, double radius, double xDirection, double yDirection);
|
SILKWORMAPI void Silkworm_PushNodesInRadius(double x, double y, double radius, double xDirection, double yDirection);
|
||||||
SILKWORMAPI void Silkworm_DestroyNodesInRadius(double x, double y, double radius);
|
SILKWORMAPI void Silkworm_DestroyNodesInRadius(double x, double y, double radius);
|
||||||
|
SILKWORMAPI double Silkworm_DestroyClothInRadius(double x, double y, double radius);
|
||||||
|
|
||||||
SILKWORMAPI void Silkworm_ClearAll();
|
SILKWORMAPI void Silkworm_ClearAll();
|
||||||
|
SILKWORMAPI void Silkworm_Finish();
|
||||||
|
|
||||||
#endif /* SILKWORM_H */
|
#endif /* SILKWORM_H */
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{6DB15344-E000-45CB-A48A-1D72F7D6E945}</ProjectGuid>
|
<ProjectGuid>{4F20502A-F926-4D12-872D-64AC2E065078}</ProjectGuid>
|
||||||
<RootNamespace>Silkworm</RootNamespace>
|
<RootNamespace>Silkworm</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
Loading…
Reference in New Issue