|
|
- /*
- By TK-Master
- */
- #include "VictoryBPLibraryPrivatePCH.h"
-
- #include "TKMathFunctionLibrary.h"
-
- #include "StaticMeshResources.h"
-
- //UTKMathFunctionLibrary
-
- float UTKMathFunctionLibrary::GetConsoleVariableFloat(FString VariableName)
- {
- const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(*VariableName);
-
- if (CVar)
- {
- return CVar->GetValueOnGameThread();
- //return CVar->GetValueOnAnyThread();
- }
-
- return 0.f;
- }
-
- int32 UTKMathFunctionLibrary::GetConsoleVariableInt(FString VariableName)
- {
- const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(*VariableName);
-
- if (CVar)
- {
- return CVar->GetValueOnGameThread();
- //return CVar->GetValueOnAnyThread();
- }
- return 0;
- }
-
- float UTKMathFunctionLibrary::NegateFloat(float A)
- {
- return -A;
- }
-
- int32 UTKMathFunctionLibrary::NegateInt(int32 A)
- {
- return -A;
- }
-
- FVector2D UTKMathFunctionLibrary::NegateVector2D(FVector2D A)
- {
- return -A;
- }
-
- FVector UTKMathFunctionLibrary::SetVectorLength(FVector A, float size)
- {
- return A.GetSafeNormal() * size;
- }
-
- FVector UTKMathFunctionLibrary::VectorRadiansToDegrees(FVector RadVector)
- {
- return FVector::RadiansToDegrees(RadVector);
- }
-
- FVector UTKMathFunctionLibrary::VectorDegreesToRadians(FVector DegVector)
- {
- return FVector::DegreesToRadians(DegVector);
- }
-
- int32 UTKMathFunctionLibrary::RoundToLowerMultiple(int32 A, int32 Multiple, bool skipSelf)
- {
- int32 result = (A / Multiple) * Multiple;
- if (skipSelf && result == A && result != 0)
- {
- return ((A-1) / Multiple) * Multiple;
- }
- return result;
- }
-
- int32 UTKMathFunctionLibrary::RoundToUpperMultiple(int32 A, int32 Multiple, bool skipSelf)
- {
- if (skipSelf || FMath::Fmod(A, Multiple) != 0)
- {
- A = ((A + Multiple) / Multiple) * Multiple;
- }
- return A;
- }
-
- int32 UTKMathFunctionLibrary::RoundToNearestMultiple(int32 A, int32 Multiple)
- {
- return ((A + Multiple / 2) / Multiple) * Multiple;
- }
-
- bool UTKMathFunctionLibrary::IsPowerOfTwo(int32 x)
- {
- //return x && ((x&-x) == x);
- return FMath::IsPowerOfTwo(x);
- }
-
- bool UTKMathFunctionLibrary::IsMultipleOf(int32 A, int32 Multiple)
- {
- return FMath::Fmod(A, Multiple) == 0;
- }
-
- bool UTKMathFunctionLibrary::IsEvenNumber(float A)
- {
- return FMath::Fmod(A, 2) == 0;
- }
-
- FVector UTKMathFunctionLibrary::ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir)
- {
- static FVector OutClosestPoint;
- FMath::SphereDistToLine(SphereOrigin, SphereRadius, LineOrigin, LineDir.GetSafeNormal(), OutClosestPoint);
- return OutClosestPoint;
- }
-
- FVector UTKMathFunctionLibrary::ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd)
- {
- return FMath::ClosestPointOnLine(LineStart, LineEnd, Point);
- }
-
- bool UTKMathFunctionLibrary::IsPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent)
- {
- FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
- return FMath::PointBoxIntersection(Point, Box);
- }
-
- bool UTKMathFunctionLibrary::SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent)
- {
- FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
- return FMath::SphereAABBIntersection(SphereOrigin, FMath::Square(SphereRadius), Box);
- }
-
- bool UTKMathFunctionLibrary::IsLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius)
- {
- return FMath::LineSphereIntersection(LineStart, LineDir, LineLength, SphereOrigin, SphereRadius);
- }
-
- bool UTKMathFunctionLibrary::LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime)
- {
- return FMath::LineExtentBoxIntersection(inBox, Start, End, Extent, HitLocation, HitNormal, HitTime);
- }
-
- float UTKMathFunctionLibrary::SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point)
- {
- return FVector::DotProduct(planeNormal, (point - planePoint));
- }
-
- FVector UTKMathFunctionLibrary::ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point)
- {
- //FVector linePointToPoint = point - linePoint;
- //float t = FVector::DotProduct(linePointToPoint, lineDir);
- //return linePoint + lineDir * t;
-
- //FVector closestPoint;
- //OutDistance = FMath::PointDistToLine(point, lineDir, linePoint, closestPoint);
- //return closestPoint;
-
- FVector SafeDir = LineDirection.GetSafeNormal();
- return LineOrigin + (SafeDir * ((Point - LineOrigin) | SafeDir));
- }
-
- void UTKMathFunctionLibrary::ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2)
- {
- FMath::SegmentDistToSegmentSafe(Line1Start, Line1End, Line2Start, Line2End, LinePoint1, LinePoint2);
- }
-
- bool UTKMathFunctionLibrary::LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2)
- {
- //Are lines coplanar?
- if (!FVector::Coplanar(LinePoint1, LineDir1, LinePoint2, LineDir2, DELTA))
- {
- return false;
- }
-
- FVector LineDir3 = LinePoint2 - LinePoint1;
- FVector CrossDir1And2 = FVector::CrossProduct(LineDir1, LineDir2);
- FVector CrossDir3And2 = FVector::CrossProduct(LineDir3, LineDir2);
-
- float s = FVector::DotProduct(CrossDir3And2, CrossDir1And2) / CrossDir1And2.SizeSquared();
-
- if (s > 1.0f || s < 0.0f)
- {
- return false;
- }
- else
- {
- IntersectionPoint = LinePoint1 + (LineDir1 * s);
- return true;
- }
- }
-
- bool UTKMathFunctionLibrary::ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2)
- {
- float a = FVector::DotProduct(lineVec1, lineVec1);
- float b = FVector::DotProduct(lineVec1, lineVec2);
- float e = FVector::DotProduct(lineVec2, lineVec2);
-
- float d = a*e - b*b;
-
- //lines are not parallel
- if (d != 0.0f)
- {
- FVector r = linePoint1 - linePoint2;
- float c = FVector::DotProduct(lineVec1, r);
- float f = FVector::DotProduct(lineVec2, r);
-
- float s = (b*f - c*e) / d;
- float t = (a*f - c*b) / d;
-
- closestPointLine1 = linePoint1 + lineVec1 * s;
- closestPointLine2 = linePoint2 + lineVec2 * t;
-
- return true;
- }
- else
- {
- return false;
- }
- }
-
- int32 UTKMathFunctionLibrary::PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point)
- {
- FVector lineVec = linePoint2 - linePoint1;
- FVector pointVec = point - linePoint1;
-
- float dot = FVector::DotProduct(pointVec, lineVec);
-
- //point is on side of linePoint2, compared to linePoint1
- if (dot > 0)
- {
- //point is on the line segment
- if (pointVec.Size() <= lineVec.Size())
- {
- return 0;
- }
-
- //point is not on the line segment and it is on the side of linePoint2
- else
- {
- return 2;
- }
- }
-
- //Point is not on side of linePoint2, compared to linePoint1.
- //Point is not on the line segment and it is on the side of linePoint1.
- else
- {
- return 1;
- }
- }
-
- bool UTKMathFunctionLibrary::AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2)
- {
- FVector closestPointA;
- FVector closestPointB;
- int32 sideA;
- int32 sideB;
-
- FVector lineVecA = pointA2 - pointA1;
- FVector lineVecB = pointB2 - pointB1;
-
- bool valid = ClosestPointsOnTwoLines(closestPointA, closestPointB, pointA1, lineVecA.GetSafeNormal(), pointB1, lineVecB.GetSafeNormal());
-
- //lines are not parallel
- if (valid)
- {
- sideA = PointOnWhichSideOfLineSegment(pointA1, pointA2, closestPointA);
- sideB = PointOnWhichSideOfLineSegment(pointB1, pointB2, closestPointB);
-
- if ((sideA == 0) && (sideB == 0))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- //lines are parallel
- else
- {
- return false;
- }
- }
-
- FVector UTKMathFunctionLibrary::GridSnap(FVector A, float Grid)
- {
- return A.GridSnap(Grid);
- }
-
- void UTKMathFunctionLibrary::ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets)
- {
- if (CurrentAnchor.Minimum == TargetAnchor.Minimum && CurrentAnchor.Maximum == TargetAnchor.Maximum)
- {
- ConvertedOffsets = Offsets;
- return;
- }
-
- FVector2D View = FVector2D(1, 1);
- UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
- if (World && World->IsGameWorld())
- {
- if (UGameViewportClient* ViewportClient = World->GetGameViewport())
- {
- ViewportClient->GetViewportSize(View);
- }
- }
-
- FMargin ZeroAnchorOffsets = Offsets;
- //Convert to 0,0 anchor first.
- if (CurrentAnchor.Minimum != FVector2D(0, 0) || CurrentAnchor.Maximum != FVector2D(0, 0))
- {
- ZeroAnchorOffsets.Left = View.X * CurrentAnchor.Minimum.X + Offsets.Left;
- ZeroAnchorOffsets.Top = View.Y * CurrentAnchor.Minimum.Y + Offsets.Top;
-
- if (CurrentAnchor.Minimum.X != CurrentAnchor.Maximum.X)
- {
- ZeroAnchorOffsets.Right = View.X * CurrentAnchor.Maximum.X - (Offsets.Right + Offsets.Left);
- }
- if (CurrentAnchor.Minimum.Y != CurrentAnchor.Maximum.Y)
- {
- ZeroAnchorOffsets.Bottom = View.Y * CurrentAnchor.Maximum.Y - (Offsets.Bottom + Offsets.Top);
- }
-
- if (TargetAnchor.Minimum == FVector2D(0, 0) && TargetAnchor.Maximum == FVector2D(0, 0))
- {
- ConvertedOffsets = ZeroAnchorOffsets;
- return;
- }
- }
-
- //Convert 0,0 anchor offsets to target anchor offsets.
- ConvertedOffsets.Left = (-View.X) * TargetAnchor.Minimum.X + ZeroAnchorOffsets.Left;
- ConvertedOffsets.Top = (-View.Y) * TargetAnchor.Minimum.Y + ZeroAnchorOffsets.Top;
-
- ConvertedOffsets.Right = TargetAnchor.Minimum.X != TargetAnchor.Maximum.X ? View.X * TargetAnchor.Maximum.X - (ZeroAnchorOffsets.Left + ZeroAnchorOffsets.Right) : ZeroAnchorOffsets.Right;
- ConvertedOffsets.Bottom = TargetAnchor.Minimum.Y != TargetAnchor.Maximum.Y ? View.Y * TargetAnchor.Maximum.Y - (ZeroAnchorOffsets.Top + ZeroAnchorOffsets.Bottom) : ZeroAnchorOffsets.Bottom;
- }
-
-
- float UTKMathFunctionLibrary::ConvertPhysicsLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit)
- {
- if (Velocity.IsZero()) return 0.f;
-
- float unit = 0;
- switch (SpeedUnit)
- {
- case CentimeterPerSecond:
- unit = 1;
- break;
- case FootPerSecond:
- unit = 0.03280839895013;
- break;
- case MeterPerSecond:
- unit = 0.01;
- break;
- case MeterPerMinute:
- unit = 0.6;
- break;
- case KilometerPerSecond:
- unit = 0.00001;
- case KilometerPerMinute:
- unit = 0.0006;
- break;
- case KilometerPerHour:
- unit = 0.036;
- break;
- case MilePerHour:
- unit = 0.02236936292054;
- break;
- case Knot:
- unit = 0.01943844492441;
- break;
- case Mach:
- unit = 0.00002915451895044;
- break;
- case SpeedOfLight:
- unit = 3.335640951982E-11;
- break;
- case YardPerSecond:
- unit = 0.01093613298338;
- break;
- default:
- break;
- };
-
- return Velocity.Size() * unit;
- }
-
- FVector UTKMathFunctionLibrary::GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName, bool DrawDebugInfo)
- {
-
- //FTransform Transform = Target->GetComponentTransform();
- //FVector LocalLinearVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsLinearVelocity());
- //FVector LocalAngularVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsAngularVelocity());
- //FVector ResultPointVelocity = LocalLinearVelocity + FVector::CrossProduct(FVector::DegreesToRadians(LocalAngularVelocity), Transform.InverseTransformVectorNoScale(Point - Target->GetCenterOfMass()));
-
-
- if (!Target) return FVector::ZeroVector;
-
- //You can actually get it from the physx body instance instead.
- FBodyInstance* BI = Target->GetBodyInstance(BoneName);
- if (BI && BI->IsValidBodyInstance())
- {
- FVector PointVelocity = BI->GetUnrealWorldVelocityAtPoint(Point);
-
- UWorld* TheWorld = Target->GetWorld();
- if (DrawDebugInfo && TheWorld)
- {
- FColor DefaultColor(255,200,0);
- DrawDebugPoint(TheWorld, Point, 10, DefaultColor);
- DrawDebugString(TheWorld, Point, FString::SanitizeFloat(PointVelocity.Size()), NULL, FColor::White, 0.0f);
- }
-
- return PointVelocity;
- }
- return FVector::ZeroVector;
- }
-
- void UTKMathFunctionLibrary::SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName)
- {
- if (!Target) return;
-
- FBodyInstance* BI = Target->GetBodyInstance(BoneName);
- if (BI && BI->IsValidBodyInstance())
- {
- BI->COMNudge = Offset;
- BI->UpdateMassProperties();
- }
- }
|