various rope fixes
parent
4a21f5eba8
commit
8d298e84a0
113
src/Silkworm.c
113
src/Silkworm.c
|
@ -70,6 +70,7 @@ typedef struct Silkworm_Node
|
|||
float radius;
|
||||
bool pinned;
|
||||
float pushFactor;
|
||||
float windFactor;
|
||||
bool destroyable;
|
||||
|
||||
bool markedForDestroy; /* mutual recursion on nodes/links so this makes it easier to track destroys */
|
||||
|
@ -280,7 +281,6 @@ static inline void LinkTriangleHashTable_Insert(
|
|||
typedef struct Silkworm_Cloth
|
||||
{
|
||||
uint64_t id;
|
||||
float windFactor;
|
||||
|
||||
uint32_t horizontalNodeCount;
|
||||
uint32_t verticalNodeCount;
|
||||
|
@ -733,7 +733,7 @@ void Silkworm_Update(double deltaTime)
|
|||
Silkworm_PerformDestroys();
|
||||
}
|
||||
|
||||
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, double windFactor)
|
||||
{
|
||||
Silkworm_Node* node = malloc(sizeof(Silkworm_Node));
|
||||
uint64_t id;
|
||||
|
@ -766,6 +766,7 @@ double Silkworm_CreateNode(double xPosition, double yPosition, double mass, doub
|
|||
node->friction = (float)friction;
|
||||
node->radius = (float)radius;
|
||||
node->pushFactor = (float)pushFactor;
|
||||
node->windFactor = (float)windFactor;
|
||||
node->pinned = false;
|
||||
node->destroyable = false;
|
||||
node->markedForDestroy = false;
|
||||
|
@ -860,7 +861,6 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double width, do
|
|||
|
||||
Silkworm_Cloth* cloth = malloc(sizeof(Silkworm_Cloth));
|
||||
|
||||
cloth->windFactor = (float)windFactor;
|
||||
cloth->horizontalNodeCount = ((uint32_t)width / context->clothDensity) + 1;
|
||||
cloth->verticalNodeCount = ((uint32_t)height / context->clothDensity) + 1;
|
||||
cloth->nodeIndices = malloc(sizeof(uint64_t*) * cloth->horizontalNodeCount);
|
||||
|
@ -903,7 +903,7 @@ double Silkworm_CreateCloth(double xPosition, double yPosition, double width, do
|
|||
|
||||
for (j = 0; j < cloth->verticalNodeCount; j += 1)
|
||||
{
|
||||
uint64_t nodeId = (uint64_t) Silkworm_CreateNode(xPosition + i * context->clothDensity, yPosition + j * context->clothDensity, mass, friction, 1, 1.0);
|
||||
uint64_t nodeId = (uint64_t) Silkworm_CreateNode(xPosition + i * context->clothDensity, yPosition + j * context->clothDensity, mass, friction, 1, 1.0, windFactor);
|
||||
|
||||
cloth->nodeIndices[i][j] = nodeId;
|
||||
|
||||
|
@ -1075,29 +1075,17 @@ void Silkworm_ClothFillNodeDataBuffer(double clothId)
|
|||
|
||||
void Silkworm_ApplyWind(double xSpeed, double ySpeed)
|
||||
{
|
||||
uint32_t i, j, k;
|
||||
Silkworm_Cloth* cloth;
|
||||
uint32_t i;
|
||||
Silkworm_Node* node;
|
||||
|
||||
for (i = 0; i < context->clothCount; i += 1)
|
||||
for (i = 0; i < context->nodeCount; i += 1)
|
||||
{
|
||||
if (context->cloths[i] != NULL)
|
||||
node = LookupNode(i);
|
||||
|
||||
if (node != NULL && !node->pinned)
|
||||
{
|
||||
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.025f * cloth->windFactor;
|
||||
node->position.y += (float)ySpeed * 0.025f * cloth->windFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
node->position.x += (float)xSpeed * 0.025f * node->windFactor;
|
||||
node->position.y += (float)ySpeed * 0.025f * node->windFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1234,7 +1222,7 @@ double Silkworm_RopeAddNode(double ropeId, double xPosition, double yPosition, d
|
|||
|
||||
if (rope != NULL)
|
||||
{
|
||||
double nodeId = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor);
|
||||
double nodeId = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor, rope->windFactor);
|
||||
|
||||
rope->nodeIndices = realloc(rope->nodeIndices, sizeof(uint64_t) * (rope->nodeCount + 1));
|
||||
rope->nodeIndices[rope->nodeCount] = nodeId;
|
||||
|
@ -1259,16 +1247,20 @@ double Silkworm_RopeVerticalLength(double ropeId)
|
|||
|
||||
if (rope != NULL)
|
||||
{
|
||||
/* return the distance between the end node Y and the start Y */
|
||||
return LookupNode(rope->nodeIndices[rope->nodeCount - 1])->position.y - LookupNode(rope->nodeIndices[0])->position.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
Silkworm_Node* startNode = LookupNode(rope->nodeIndices[0]);
|
||||
Silkworm_Node* endNode = LookupNode(rope->nodeIndices[rope->nodeCount - 1]);
|
||||
|
||||
if (startNode != NULL && endNode != NULL)
|
||||
{
|
||||
/* return the distance between the end node Y and the start Y */
|
||||
return fabs(endNode->position.y - startNode->position.y);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
double Silkworm_NearestX(double ropeId, double xPosition, double yPosition)
|
||||
double Silkworm_RopeNearestX(double ropeId, double xPosition, double yPosition)
|
||||
{
|
||||
uint32_t i;
|
||||
float nearestSqrDistance, nearestX;
|
||||
|
@ -1284,15 +1276,18 @@ double Silkworm_NearestX(double ropeId, double xPosition, double yPosition)
|
|||
{
|
||||
Silkworm_Node* node = LookupNode(rope->nodeIndices[i]);
|
||||
|
||||
float yDistance = node->position.y - yPosition;
|
||||
float xDistance = node->position.x - xPosition;
|
||||
|
||||
float sqrDistance = xDistance * xDistance + yDistance * yDistance;
|
||||
|
||||
if (sqrDistance < nearestSqrDistance)
|
||||
if (node != NULL)
|
||||
{
|
||||
nearestSqrDistance = sqrDistance;
|
||||
nearestX = node->position.x;
|
||||
float yDistance = node->position.y - yPosition;
|
||||
float xDistance = node->position.x - xPosition;
|
||||
|
||||
float sqrDistance = xDistance * xDistance + yDistance * yDistance;
|
||||
|
||||
if (sqrDistance < nearestSqrDistance)
|
||||
{
|
||||
nearestSqrDistance = sqrDistance;
|
||||
nearestX = node->position.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1300,7 +1295,7 @@ double Silkworm_NearestX(double ropeId, double xPosition, double yPosition)
|
|||
return nearestX;
|
||||
}
|
||||
|
||||
double Silkworm_NearestY(double ropeId, double xPosition, double yPosition)
|
||||
double Silkworm_RopeNearestY(double ropeId, double xPosition, double yPosition)
|
||||
{
|
||||
uint32_t i;
|
||||
float nearestSqrDistance, nearestY;
|
||||
|
@ -1316,15 +1311,18 @@ double Silkworm_NearestY(double ropeId, double xPosition, double yPosition)
|
|||
{
|
||||
Silkworm_Node* node = LookupNode(rope->nodeIndices[i]);
|
||||
|
||||
float yDistance = node->position.y - yPosition;
|
||||
float xDistance = node->position.x - xPosition;
|
||||
|
||||
float sqrDistance = xDistance * xDistance + yDistance * yDistance;
|
||||
|
||||
if (sqrDistance < nearestSqrDistance)
|
||||
if (node != NULL)
|
||||
{
|
||||
nearestSqrDistance = sqrDistance;
|
||||
nearestY = node->position.y;
|
||||
float yDistance = node->position.y - yPosition;
|
||||
float xDistance = node->position.x - xPosition;
|
||||
|
||||
float sqrDistance = xDistance * xDistance + yDistance * yDistance;
|
||||
|
||||
if (sqrDistance < nearestSqrDistance)
|
||||
{
|
||||
nearestSqrDistance = sqrDistance;
|
||||
nearestY = node->position.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1332,6 +1330,18 @@ double Silkworm_NearestY(double ropeId, double xPosition, double yPosition)
|
|||
return nearestY;
|
||||
}
|
||||
|
||||
void Silkworm_UnpinRope(double ropeId)
|
||||
{
|
||||
Silkworm_Rope* rope = LookupRope(ropeId);
|
||||
|
||||
Silkworm_Node* node = LookupNode(rope->nodeIndices[0]);
|
||||
|
||||
if (node != NULL)
|
||||
{
|
||||
node->pinned = false;
|
||||
}
|
||||
}
|
||||
|
||||
double Silkworm_RopeCreate(double xPosition, double yPosition, double mass, double friction, double windFactor, double pushFactor, double tearThreshold)
|
||||
{
|
||||
Silkworm_Rope* rope = malloc(sizeof(Silkworm_Rope));
|
||||
|
@ -1366,7 +1376,7 @@ double Silkworm_RopeCreate(double xPosition, double yPosition, double mass, doub
|
|||
rope->nodeIndices = malloc(sizeof(uint64_t));
|
||||
rope->nodeCount = 1;
|
||||
|
||||
rope->nodeIndices[0] = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor);
|
||||
rope->nodeIndices[0] = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor, rope->windFactor);
|
||||
|
||||
Silkworm_Node* node = LookupNode(rope->nodeIndices[0]);
|
||||
node->pinned = true;
|
||||
|
@ -1397,6 +1407,9 @@ void Silkworm_RopeDestroy(double ropeId)
|
|||
}
|
||||
|
||||
free(rope->nodeIndices);
|
||||
|
||||
context->ropes[rope->id] = NULL;
|
||||
free(rope);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1829,7 +1842,7 @@ void Silkworm_DestroyNodesInRadius(double x, double y, double radius)
|
|||
{
|
||||
Silkworm_Node* node = context->nodes[i];
|
||||
|
||||
if (node != NULL)
|
||||
if (node != NULL && node->destroyable)
|
||||
{
|
||||
float xDistance = (float)fabs((float)x - node->position.x);
|
||||
float yDistance = (float)fabs((float)y - node->position.y);
|
||||
|
|
|
@ -62,7 +62,7 @@ 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, double windFactor);
|
||||
|
||||
SILKWORMAPI void Silkworm_NodeSetDestroyable(double nodeId);
|
||||
|
||||
|
@ -82,8 +82,9 @@ SILKWORMAPI double Silkworm_ClothFillTriangleBuffer(double clothId, double leftU
|
|||
SILKWORMAPI double Silkworm_RopeCreate(double xPosition, double yPosition, double mass, double friction, double windFactor, double pushFactor, double tearThreshold);
|
||||
SILKWORMAPI double Silkworm_RopeAddNode(double ropeId, double xPosition, double yPosition, double length);
|
||||
SILKWORMAPI double Silkworm_RopeVerticalLength(double ropeId);
|
||||
SILKWORMAPI double Silkworm_NearestX(double ropeId, double xPosition, double yPosition);
|
||||
SILKWORMAPI double Silkworm_NearestY(double ropeId, double xPosition, double yPosition);
|
||||
SILKWORMAPI double Silkworm_RopeNearestX(double ropeId, double xPosition, double yPosition);
|
||||
SILKWORMAPI double Silkworm_RopeNearestY(double ropeId, double xPosition, double yPosition);
|
||||
SILKWORMAPI void Silkworm_UnpinRope(double ropeId);
|
||||
SILKWORMAPI void Silkworm_RopeDestroy(double ropeId);
|
||||
SILKWORMAPI double Silkworm_RopeRequiredBufferSize(double ropeId);
|
||||
SILKWORMAPI double Silkworm_RopeFillBuffer(double ropeId, double width, double leftUV, double widthUV, double topUV, double heightUV);
|
||||
|
|
Loading…
Reference in New Issue