A modded EditSaber for making beat saber maps.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

429 lines
12 KiB

/*
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();
}
}