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

  1. /*
  2. By TK-Master
  3. */
  4. #include "VictoryBPLibraryPrivatePCH.h"
  5. #include "TKMathFunctionLibrary.h"
  6. #include "StaticMeshResources.h"
  7. //UTKMathFunctionLibrary
  8. float UTKMathFunctionLibrary::GetConsoleVariableFloat(FString VariableName)
  9. {
  10. const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(*VariableName);
  11. if (CVar)
  12. {
  13. return CVar->GetValueOnGameThread();
  14. //return CVar->GetValueOnAnyThread();
  15. }
  16. return 0.f;
  17. }
  18. int32 UTKMathFunctionLibrary::GetConsoleVariableInt(FString VariableName)
  19. {
  20. const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(*VariableName);
  21. if (CVar)
  22. {
  23. return CVar->GetValueOnGameThread();
  24. //return CVar->GetValueOnAnyThread();
  25. }
  26. return 0;
  27. }
  28. float UTKMathFunctionLibrary::NegateFloat(float A)
  29. {
  30. return -A;
  31. }
  32. int32 UTKMathFunctionLibrary::NegateInt(int32 A)
  33. {
  34. return -A;
  35. }
  36. FVector2D UTKMathFunctionLibrary::NegateVector2D(FVector2D A)
  37. {
  38. return -A;
  39. }
  40. FVector UTKMathFunctionLibrary::SetVectorLength(FVector A, float size)
  41. {
  42. return A.GetSafeNormal() * size;
  43. }
  44. FVector UTKMathFunctionLibrary::VectorRadiansToDegrees(FVector RadVector)
  45. {
  46. return FVector::RadiansToDegrees(RadVector);
  47. }
  48. FVector UTKMathFunctionLibrary::VectorDegreesToRadians(FVector DegVector)
  49. {
  50. return FVector::DegreesToRadians(DegVector);
  51. }
  52. int32 UTKMathFunctionLibrary::RoundToLowerMultiple(int32 A, int32 Multiple, bool skipSelf)
  53. {
  54. int32 result = (A / Multiple) * Multiple;
  55. if (skipSelf && result == A && result != 0)
  56. {
  57. return ((A-1) / Multiple) * Multiple;
  58. }
  59. return result;
  60. }
  61. int32 UTKMathFunctionLibrary::RoundToUpperMultiple(int32 A, int32 Multiple, bool skipSelf)
  62. {
  63. if (skipSelf || FMath::Fmod(A, Multiple) != 0)
  64. {
  65. A = ((A + Multiple) / Multiple) * Multiple;
  66. }
  67. return A;
  68. }
  69. int32 UTKMathFunctionLibrary::RoundToNearestMultiple(int32 A, int32 Multiple)
  70. {
  71. return ((A + Multiple / 2) / Multiple) * Multiple;
  72. }
  73. bool UTKMathFunctionLibrary::IsPowerOfTwo(int32 x)
  74. {
  75. //return x && ((x&-x) == x);
  76. return FMath::IsPowerOfTwo(x);
  77. }
  78. bool UTKMathFunctionLibrary::IsMultipleOf(int32 A, int32 Multiple)
  79. {
  80. return FMath::Fmod(A, Multiple) == 0;
  81. }
  82. bool UTKMathFunctionLibrary::IsEvenNumber(float A)
  83. {
  84. return FMath::Fmod(A, 2) == 0;
  85. }
  86. FVector UTKMathFunctionLibrary::ClosestPointOnSphereToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir)
  87. {
  88. static FVector OutClosestPoint;
  89. FMath::SphereDistToLine(SphereOrigin, SphereRadius, LineOrigin, LineDir.GetSafeNormal(), OutClosestPoint);
  90. return OutClosestPoint;
  91. }
  92. FVector UTKMathFunctionLibrary::ClosestPointOnLineSeqment(FVector Point, FVector LineStart, FVector LineEnd)
  93. {
  94. return FMath::ClosestPointOnLine(LineStart, LineEnd, Point);
  95. }
  96. bool UTKMathFunctionLibrary::IsPointInsideBox(FVector Point, FVector BoxOrigin, FVector BoxExtent)
  97. {
  98. FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
  99. return FMath::PointBoxIntersection(Point, Box);
  100. }
  101. bool UTKMathFunctionLibrary::SphereBoxIntersection(FVector SphereOrigin, float SphereRadius, FVector BoxOrigin, FVector BoxExtent)
  102. {
  103. FBox Box = FBox::BuildAABB(BoxOrigin, BoxExtent);
  104. return FMath::SphereAABBIntersection(SphereOrigin, FMath::Square(SphereRadius), Box);
  105. }
  106. bool UTKMathFunctionLibrary::IsLineInsideSphere(FVector LineStart, FVector LineDir, float LineLength, FVector SphereOrigin, float SphereRadius)
  107. {
  108. return FMath::LineSphereIntersection(LineStart, LineDir, LineLength, SphereOrigin, SphereRadius);
  109. }
  110. bool UTKMathFunctionLibrary::LineExtentBoxIntersection(FBox inBox, FVector Start, FVector End, FVector Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime)
  111. {
  112. return FMath::LineExtentBoxIntersection(inBox, Start, End, Extent, HitLocation, HitNormal, HitTime);
  113. }
  114. float UTKMathFunctionLibrary::SignedDistancePlanePoint(FVector planeNormal, FVector planePoint, FVector point)
  115. {
  116. return FVector::DotProduct(planeNormal, (point - planePoint));
  117. }
  118. FVector UTKMathFunctionLibrary::ProjectPointOnLine(FVector LineOrigin, FVector LineDirection, FVector Point)
  119. {
  120. //FVector linePointToPoint = point - linePoint;
  121. //float t = FVector::DotProduct(linePointToPoint, lineDir);
  122. //return linePoint + lineDir * t;
  123. //FVector closestPoint;
  124. //OutDistance = FMath::PointDistToLine(point, lineDir, linePoint, closestPoint);
  125. //return closestPoint;
  126. FVector SafeDir = LineDirection.GetSafeNormal();
  127. return LineOrigin + (SafeDir * ((Point - LineOrigin) | SafeDir));
  128. }
  129. void UTKMathFunctionLibrary::ClosestPointsOfLineSegments(FVector Line1Start, FVector Line1End, FVector Line2Start, FVector Line2End, FVector& LinePoint1, FVector& LinePoint2)
  130. {
  131. FMath::SegmentDistToSegmentSafe(Line1Start, Line1End, Line2Start, Line2End, LinePoint1, LinePoint2);
  132. }
  133. bool UTKMathFunctionLibrary::LineToLineIntersection(FVector& IntersectionPoint, FVector LinePoint1, FVector LineDir1, FVector LinePoint2, FVector LineDir2)
  134. {
  135. //Are lines coplanar?
  136. if (!FVector::Coplanar(LinePoint1, LineDir1, LinePoint2, LineDir2, DELTA))
  137. {
  138. return false;
  139. }
  140. FVector LineDir3 = LinePoint2 - LinePoint1;
  141. FVector CrossDir1And2 = FVector::CrossProduct(LineDir1, LineDir2);
  142. FVector CrossDir3And2 = FVector::CrossProduct(LineDir3, LineDir2);
  143. float s = FVector::DotProduct(CrossDir3And2, CrossDir1And2) / CrossDir1And2.SizeSquared();
  144. if (s > 1.0f || s < 0.0f)
  145. {
  146. return false;
  147. }
  148. else
  149. {
  150. IntersectionPoint = LinePoint1 + (LineDir1 * s);
  151. return true;
  152. }
  153. }
  154. bool UTKMathFunctionLibrary::ClosestPointsOnTwoLines(FVector& closestPointLine1, FVector& closestPointLine2, FVector linePoint1, FVector lineVec1, FVector linePoint2, FVector lineVec2)
  155. {
  156. float a = FVector::DotProduct(lineVec1, lineVec1);
  157. float b = FVector::DotProduct(lineVec1, lineVec2);
  158. float e = FVector::DotProduct(lineVec2, lineVec2);
  159. float d = a*e - b*b;
  160. //lines are not parallel
  161. if (d != 0.0f)
  162. {
  163. FVector r = linePoint1 - linePoint2;
  164. float c = FVector::DotProduct(lineVec1, r);
  165. float f = FVector::DotProduct(lineVec2, r);
  166. float s = (b*f - c*e) / d;
  167. float t = (a*f - c*b) / d;
  168. closestPointLine1 = linePoint1 + lineVec1 * s;
  169. closestPointLine2 = linePoint2 + lineVec2 * t;
  170. return true;
  171. }
  172. else
  173. {
  174. return false;
  175. }
  176. }
  177. int32 UTKMathFunctionLibrary::PointOnWhichSideOfLineSegment(FVector linePoint1, FVector linePoint2, FVector point)
  178. {
  179. FVector lineVec = linePoint2 - linePoint1;
  180. FVector pointVec = point - linePoint1;
  181. float dot = FVector::DotProduct(pointVec, lineVec);
  182. //point is on side of linePoint2, compared to linePoint1
  183. if (dot > 0)
  184. {
  185. //point is on the line segment
  186. if (pointVec.Size() <= lineVec.Size())
  187. {
  188. return 0;
  189. }
  190. //point is not on the line segment and it is on the side of linePoint2
  191. else
  192. {
  193. return 2;
  194. }
  195. }
  196. //Point is not on side of linePoint2, compared to linePoint1.
  197. //Point is not on the line segment and it is on the side of linePoint1.
  198. else
  199. {
  200. return 1;
  201. }
  202. }
  203. bool UTKMathFunctionLibrary::AreLineSegmentsCrossing(FVector pointA1, FVector pointA2, FVector pointB1, FVector pointB2)
  204. {
  205. FVector closestPointA;
  206. FVector closestPointB;
  207. int32 sideA;
  208. int32 sideB;
  209. FVector lineVecA = pointA2 - pointA1;
  210. FVector lineVecB = pointB2 - pointB1;
  211. bool valid = ClosestPointsOnTwoLines(closestPointA, closestPointB, pointA1, lineVecA.GetSafeNormal(), pointB1, lineVecB.GetSafeNormal());
  212. //lines are not parallel
  213. if (valid)
  214. {
  215. sideA = PointOnWhichSideOfLineSegment(pointA1, pointA2, closestPointA);
  216. sideB = PointOnWhichSideOfLineSegment(pointB1, pointB2, closestPointB);
  217. if ((sideA == 0) && (sideB == 0))
  218. {
  219. return true;
  220. }
  221. else
  222. {
  223. return false;
  224. }
  225. }
  226. //lines are parallel
  227. else
  228. {
  229. return false;
  230. }
  231. }
  232. FVector UTKMathFunctionLibrary::GridSnap(FVector A, float Grid)
  233. {
  234. return A.GridSnap(Grid);
  235. }
  236. void UTKMathFunctionLibrary::ConvertAnchorToAnchor(UObject* WorldContextObject, FAnchors CurrentAnchor, FMargin Offsets, FAnchors TargetAnchor, FMargin& ConvertedOffsets)
  237. {
  238. if (CurrentAnchor.Minimum == TargetAnchor.Minimum && CurrentAnchor.Maximum == TargetAnchor.Maximum)
  239. {
  240. ConvertedOffsets = Offsets;
  241. return;
  242. }
  243. FVector2D View = FVector2D(1, 1);
  244. UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
  245. if (World && World->IsGameWorld())
  246. {
  247. if (UGameViewportClient* ViewportClient = World->GetGameViewport())
  248. {
  249. ViewportClient->GetViewportSize(View);
  250. }
  251. }
  252. FMargin ZeroAnchorOffsets = Offsets;
  253. //Convert to 0,0 anchor first.
  254. if (CurrentAnchor.Minimum != FVector2D(0, 0) || CurrentAnchor.Maximum != FVector2D(0, 0))
  255. {
  256. ZeroAnchorOffsets.Left = View.X * CurrentAnchor.Minimum.X + Offsets.Left;
  257. ZeroAnchorOffsets.Top = View.Y * CurrentAnchor.Minimum.Y + Offsets.Top;
  258. if (CurrentAnchor.Minimum.X != CurrentAnchor.Maximum.X)
  259. {
  260. ZeroAnchorOffsets.Right = View.X * CurrentAnchor.Maximum.X - (Offsets.Right + Offsets.Left);
  261. }
  262. if (CurrentAnchor.Minimum.Y != CurrentAnchor.Maximum.Y)
  263. {
  264. ZeroAnchorOffsets.Bottom = View.Y * CurrentAnchor.Maximum.Y - (Offsets.Bottom + Offsets.Top);
  265. }
  266. if (TargetAnchor.Minimum == FVector2D(0, 0) && TargetAnchor.Maximum == FVector2D(0, 0))
  267. {
  268. ConvertedOffsets = ZeroAnchorOffsets;
  269. return;
  270. }
  271. }
  272. //Convert 0,0 anchor offsets to target anchor offsets.
  273. ConvertedOffsets.Left = (-View.X) * TargetAnchor.Minimum.X + ZeroAnchorOffsets.Left;
  274. ConvertedOffsets.Top = (-View.Y) * TargetAnchor.Minimum.Y + ZeroAnchorOffsets.Top;
  275. ConvertedOffsets.Right = TargetAnchor.Minimum.X != TargetAnchor.Maximum.X ? View.X * TargetAnchor.Maximum.X - (ZeroAnchorOffsets.Left + ZeroAnchorOffsets.Right) : ZeroAnchorOffsets.Right;
  276. ConvertedOffsets.Bottom = TargetAnchor.Minimum.Y != TargetAnchor.Maximum.Y ? View.Y * TargetAnchor.Maximum.Y - (ZeroAnchorOffsets.Top + ZeroAnchorOffsets.Bottom) : ZeroAnchorOffsets.Bottom;
  277. }
  278. float UTKMathFunctionLibrary::ConvertPhysicsLinearVelocity(FVector Velocity, TEnumAsByte<enum ESpeedUnit> SpeedUnit)
  279. {
  280. if (Velocity.IsZero()) return 0.f;
  281. float unit = 0;
  282. switch (SpeedUnit)
  283. {
  284. case CentimeterPerSecond:
  285. unit = 1;
  286. break;
  287. case FootPerSecond:
  288. unit = 0.03280839895013;
  289. break;
  290. case MeterPerSecond:
  291. unit = 0.01;
  292. break;
  293. case MeterPerMinute:
  294. unit = 0.6;
  295. break;
  296. case KilometerPerSecond:
  297. unit = 0.00001;
  298. case KilometerPerMinute:
  299. unit = 0.0006;
  300. break;
  301. case KilometerPerHour:
  302. unit = 0.036;
  303. break;
  304. case MilePerHour:
  305. unit = 0.02236936292054;
  306. break;
  307. case Knot:
  308. unit = 0.01943844492441;
  309. break;
  310. case Mach:
  311. unit = 0.00002915451895044;
  312. break;
  313. case SpeedOfLight:
  314. unit = 3.335640951982E-11;
  315. break;
  316. case YardPerSecond:
  317. unit = 0.01093613298338;
  318. break;
  319. default:
  320. break;
  321. };
  322. return Velocity.Size() * unit;
  323. }
  324. FVector UTKMathFunctionLibrary::GetVelocityAtPoint(UPrimitiveComponent* Target, FVector Point, FName BoneName, bool DrawDebugInfo)
  325. {
  326. //FTransform Transform = Target->GetComponentTransform();
  327. //FVector LocalLinearVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsLinearVelocity());
  328. //FVector LocalAngularVelocity = Transform.InverseTransformVectorNoScale(Target->GetPhysicsAngularVelocity());
  329. //FVector ResultPointVelocity = LocalLinearVelocity + FVector::CrossProduct(FVector::DegreesToRadians(LocalAngularVelocity), Transform.InverseTransformVectorNoScale(Point - Target->GetCenterOfMass()));
  330. if (!Target) return FVector::ZeroVector;
  331. //You can actually get it from the physx body instance instead.
  332. FBodyInstance* BI = Target->GetBodyInstance(BoneName);
  333. if (BI && BI->IsValidBodyInstance())
  334. {
  335. FVector PointVelocity = BI->GetUnrealWorldVelocityAtPoint(Point);
  336. UWorld* TheWorld = Target->GetWorld();
  337. if (DrawDebugInfo && TheWorld)
  338. {
  339. FColor DefaultColor(255,200,0);
  340. DrawDebugPoint(TheWorld, Point, 10, DefaultColor);
  341. DrawDebugString(TheWorld, Point, FString::SanitizeFloat(PointVelocity.Size()), NULL, FColor::White, 0.0f);
  342. }
  343. return PointVelocity;
  344. }
  345. return FVector::ZeroVector;
  346. }
  347. void UTKMathFunctionLibrary::SetCenterOfMassOffset(UPrimitiveComponent* Target, FVector Offset, FName BoneName)
  348. {
  349. if (!Target) return;
  350. FBodyInstance* BI = Target->GetBodyInstance(BoneName);
  351. if (BI && BI->IsValidBodyInstance())
  352. {
  353. BI->COMNudge = Offset;
  354. BI->UpdateMassProperties();
  355. }
  356. }