diff --git a/src/Silkworm.c b/src/Silkworm.c index 7598379..107ecd3 100644 --- a/src/Silkworm.c +++ b/src/Silkworm.c @@ -1232,18 +1232,104 @@ double Silkworm_RopeAddNode(double ropeId, double xPosition, double yPosition, d { Silkworm_Rope *rope = LookupRope(ropeId); - double nodeId = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor); + if (rope != NULL) + { + double nodeId = Silkworm_CreateNode(xPosition, yPosition, rope->nodeMass, rope->friction, 1.0, rope->pushFactor); - rope->nodeIndices = realloc(rope->nodeIndices, sizeof(uint64_t) * (rope->nodeCount + 1)); - rope->nodeIndices[rope->nodeCount] = nodeId; - rope->nodeCount += 1; + rope->nodeIndices = realloc(rope->nodeIndices, sizeof(uint64_t) * (rope->nodeCount + 1)); + rope->nodeIndices[rope->nodeCount] = nodeId; + rope->nodeCount += 1; - Silkworm_Node* node = LookupNode((uint64_t)nodeId); - node->destroyable = false; + Silkworm_Node* node = LookupNode((uint64_t)nodeId); + node->destroyable = false; - Silkworm_CreateLink((double)rope->nodeIndices[rope->nodeCount - 2], (double)rope->nodeIndices[rope->nodeCount - 1], length, rope->tearThreshold); + Silkworm_CreateLink((double)rope->nodeIndices[rope->nodeCount - 2], (double)rope->nodeIndices[rope->nodeCount - 1], length, rope->tearThreshold); - return nodeId; + return nodeId; + } + else + { + return -1; + } +} + +double Silkworm_RopeVerticalLength(double ropeId) +{ + Silkworm_Rope* rope = LookupRope(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; + } +} + +double Silkworm_NearestX(double ropeId, double xPosition, double yPosition) +{ + uint32_t i; + float nearestSqrDistance, nearestX; + + nearestSqrDistance = 9999999999.0f; + nearestX = 9999999999.0f; + + Silkworm_Rope* rope = LookupRope(ropeId); + + if (rope != NULL) + { + for (i = 0; i < rope->nodeCount; i += 1) + { + 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) + { + nearestSqrDistance = sqrDistance; + nearestX = node->position.x; + } + } + } + + return nearestX; +} + +double Silkworm_NearestY(double ropeId, double xPosition, double yPosition) +{ + uint32_t i; + float nearestSqrDistance, nearestY; + + nearestSqrDistance = 9999999999.0f; + nearestY = 9999999999.0f; + + Silkworm_Rope* rope = LookupRope(ropeId); + + if (rope != NULL) + { + for (i = 0; i < rope->nodeCount; i += 1) + { + 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) + { + nearestSqrDistance = sqrDistance; + nearestY = node->position.y; + } + } + } + + return nearestY; } double Silkworm_RopeCreate(double xPosition, double yPosition, double mass, double friction, double windFactor, double pushFactor, double tearThreshold) diff --git a/src/Silkworm.h b/src/Silkworm.h index 898e5ce..0cb1c86 100644 --- a/src/Silkworm.h +++ b/src/Silkworm.h @@ -81,6 +81,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 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);