diff --git a/include/Geometry.h b/include/Geometry.h index 57b38f20..85009bcc 100644 --- a/include/Geometry.h +++ b/include/Geometry.h @@ -7,23 +7,23 @@ struct Sphere; /** - * @brief TODO + * @brief A representation of a cylinder in 3D space. */ struct Cylinder { - Cylinder(Vector3f& p1, Vector3f& p2, f32 p3) - : _00(p1) - , _0C(p2) - , _18(p3) + Cylinder(Vector3f& startPoint, Vector3f& endPoint, f32 radius) + : mStartPoint(startPoint) + , mEndPoint(endPoint) + , mRadius(radius) { } - void get2dDist(Vector3f&); - void collide(const Sphere&, Vector3f&, f32&); - f32 getPosRatio(const Vector3f&); + f32 get2dDist(Vector3f& point); + void collide(const Sphere& sphere, Vector3f& point, f32& depth); + f32 getPosRatio(const Vector3f& point); // 0-1 along the cylinder axis - Vector3f _00; // _00 - Vector3f _0C; // _0C - f32 _18; // _18 + Vector3f mStartPoint; // _00 + Vector3f mEndPoint; // _0C + f32 mRadius; // _18 }; /** diff --git a/src/plugPikiKando/collInfo.cpp b/src/plugPikiKando/collInfo.cpp index 740f63b9..f71aec56 100644 --- a/src/plugPikiKando/collInfo.cpp +++ b/src/plugPikiKando/collInfo.cpp @@ -38,8 +38,34 @@ static char* _typeStr[] = { * Address: 80086CC4 * Size: 0002DC */ -void Cylinder::get2dDist(Vector3f&) +f32 Cylinder::get2dDist(Vector3f& point) { + // Calculate cylinder direction vector + Vector3f cylinderDir = mEndPoint - mStartPoint; + + Vector3f normalised = cylinderDir; + + // Project point onto cylinder axis + f32 length = normalised.normalise(); + f32 projectionRatio = normalised.DP(point - mStartPoint) / length; + + if (projectionRatio < 0.0f) { + // Before cylinder start - get 2D distance to start point + Vector3f startToPoint = mStartPoint - point; + return sqrtf(startToPoint.x * startToPoint.x + startToPoint.z * startToPoint.z); + } + + if (projectionRatio > 1.0f) { + // Past cylinder end - get 2D distance to end point + Vector3f endToPoint = mEndPoint - point; + return sqrtf(endToPoint.x * endToPoint.x + endToPoint.z * endToPoint.z); + } + + // On cylinder body - get distance to projected point + Vector3f projectedPoint = (normalised * projectionRatio) + mStartPoint; + Vector3f projToPoint = projectedPoint - point; + return sqrtf(projToPoint.x * projToPoint.x + projToPoint.z * projToPoint.z); + /* .loc_0x0: mflr r0 @@ -761,7 +787,7 @@ bool Tube::collide(const Sphere&, Vector3f&, f32&) * Address: 800876C8 * Size: 0000E4 */ -f32 Cylinder::getPosRatio(const Vector3f&) +f32 Cylinder::getPosRatio(const Vector3f& vec) { /* .loc_0x0: