315 lines
8.8 KiB
TypeScript
315 lines
8.8 KiB
TypeScript
// UE/SystemLibrary.ts
|
|
|
|
import { BlueprintFunctionLibrary } from '#root/UE/BlueprintFunctionLibrary.ts';
|
|
import type { Color } from '#root/UE/Color.ts';
|
|
import type { Float } from '#root/UE/Float.ts';
|
|
import type { Integer } from '#root/UE/Integer.ts';
|
|
import { LinearColor } from '#root/UE/LinearColor.ts';
|
|
import { Vector } from '#root/UE/Vector.ts';
|
|
|
|
/**
|
|
* System Library: Core Mathematical Functions
|
|
* Wrapper for JavaScript Math functions with UE5 compatibility
|
|
* Provides deterministic mathematical operations for movement calculations
|
|
*/
|
|
class MathLibraryClass extends BlueprintFunctionLibrary {
|
|
constructor(
|
|
outer: null | BlueprintFunctionLibrary = null,
|
|
name: string = 'MathLibrary'
|
|
) {
|
|
super(outer, name);
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// FUNCTIONS
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Convert degrees to radians
|
|
* @param Degrees - Angle in degrees
|
|
* @returns Angle in radians
|
|
* @example
|
|
* // Convert 90 degrees to radians
|
|
* DegreesToRadians(90) // returns π/2
|
|
*/
|
|
public DegreesToRadians(Degrees: Float): Float {
|
|
return (Degrees * Math.PI) / 180;
|
|
}
|
|
|
|
/**
|
|
* Convert radians to degrees
|
|
* @param Radians - Angle in radians
|
|
* @returns Angle in degrees
|
|
* @example
|
|
* // Convert π/2 radians to degrees
|
|
* RadiansToDegrees(Math.PI / 2) // returns 90
|
|
*/
|
|
public RadiansToDegrees(Radians: Float): Float {
|
|
return (Radians * 180) / Math.PI;
|
|
}
|
|
|
|
/**
|
|
* Calculate sine of angle in radians
|
|
* @param Value - Angle in radians
|
|
* @returns Sine value (-1 to 1)
|
|
*/
|
|
public Sin(Value: Float): Float {
|
|
return Math.sin(Value);
|
|
}
|
|
|
|
/**
|
|
* Calculate cosine of angle in radians
|
|
* @param Value - Angle in radians
|
|
* @returns Cosine value (-1 to 1)
|
|
*/
|
|
public Cos(Value: Float): Float {
|
|
return Math.cos(Value);
|
|
}
|
|
|
|
/**
|
|
* Calculate arccosine (inverse cosine) of value
|
|
* @param Value - Input value (-1 to 1)
|
|
* @returns Angle in radians (0 to π)
|
|
*/
|
|
public Acos(Value: Float): Float {
|
|
return Math.acos(Value);
|
|
}
|
|
|
|
/**
|
|
* Calculate arctangent2 of Y and X
|
|
* @param Y - Y coordinate
|
|
* @param X - X coordinate
|
|
* @returns Angle in radians (-π to π)
|
|
*/
|
|
public Atan2(Y: Float, X: Float): Float {
|
|
return Math.atan2(Y, X);
|
|
}
|
|
|
|
/**
|
|
* Calculate dot product of two vectors
|
|
* @param Vector1 - First vector
|
|
* @param Vector2 - Second vector
|
|
* @returns Dot product scalar value
|
|
* @example
|
|
* // Dot product of perpendicular vectors
|
|
* Dot(new Vector(1,0,0), new Vector(0,1,0)) // returns 0
|
|
*/
|
|
public Dot(Vector1: Vector, Vector2: Vector): Float {
|
|
return (
|
|
Vector1.X * Vector2.X + Vector1.Y * Vector2.Y + Vector1.Z * Vector2.Z
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Color to LinearColor conversion
|
|
* @param color - Color with 0-255 RGBA components
|
|
* @returns LinearColor with 0-1 RGBA components
|
|
* @example
|
|
* // Convert Color(255,0,0,255) to LinearColor
|
|
* ColorToLinearColor(new Color(255,0,0,255)) // returns LinearColor(1,0,0,1)
|
|
*/
|
|
public ColorToLinearColor(color: Color): LinearColor {
|
|
return new LinearColor(
|
|
color.R / 255,
|
|
color.G / 255,
|
|
color.B / 255,
|
|
color.A / 255
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Clamp a float value between a minimum and maximum
|
|
* @param Value - Value to clamp
|
|
* @param Min - Minimum limit
|
|
* @param Max - Maximum limit
|
|
* @returns Clamped value
|
|
* @example
|
|
* // Clamp 10 between 0 and 5
|
|
* Clamp(10, 0, 5) // returns 5
|
|
*/
|
|
public ClampFloat(Value: Float, Min: Float, Max: Float): Float {
|
|
return Math.min(Math.max(Value, Min), Max);
|
|
}
|
|
|
|
/**
|
|
* Calculate vector length (magnitude)
|
|
* @param Vector - Input vector
|
|
* @returns Length (magnitude) of vector
|
|
* @example
|
|
* // Length of vector (3,4,0)
|
|
* VectorLength(new Vector(3,4,0)) // returns 5
|
|
*/
|
|
public VectorLength(Vector: Vector): Float {
|
|
return Math.sqrt(
|
|
Vector.X * Vector.X + Vector.Y * Vector.Y + Vector.Z * Vector.Z
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Interpolate a float value towards a target
|
|
* @param Current - Current value
|
|
* @param Target - Target value
|
|
* @param DeltaTime - Time since last update
|
|
* @param InterpSpeed - Speed of interpolation
|
|
* @returns New interpolated value
|
|
* @example
|
|
* // Interpolate 0 towards 10 over 1 second at speed 5
|
|
* FInterpTo(0, 10, 1, 5) // returns 5
|
|
*/
|
|
public FInterpTo(
|
|
Current: Float,
|
|
Target: Float,
|
|
DeltaTime: Float,
|
|
InterpSpeed: Float
|
|
): Float {
|
|
if (InterpSpeed <= 0) {
|
|
return Target;
|
|
}
|
|
const Dist = Target - Current;
|
|
if (Dist * Dist < 0.00001) {
|
|
return Target;
|
|
}
|
|
const DeltaMove = Dist * Math.min(DeltaTime * InterpSpeed, 1);
|
|
return Current + DeltaMove;
|
|
}
|
|
|
|
/**
|
|
* Absolute value of a float
|
|
* @param Value - Input value
|
|
* @returns Absolute value
|
|
* @example
|
|
* // Absolute value of -5
|
|
* abs(-5) // returns 5
|
|
*/
|
|
public abs(Value: Float): Float {
|
|
return Math.abs(Value);
|
|
}
|
|
|
|
/**
|
|
* Interpolate a vector towards a target vector
|
|
* @param Current - Current vector
|
|
* @param Target - Target vector
|
|
* @param DeltaTime - Time since last update
|
|
* @param InterpSpeed - Speed of interpolation
|
|
* @returns New interpolated vector
|
|
* @example
|
|
* // Interpolate (0,0,0) towards (10,10,10) over 1 second at speed 5
|
|
* VInterpTo(new Vector(0,0,0), new Vector(10,10,10), 1, 5) // returns Vector(5,5,5)
|
|
*/
|
|
public VInterpTo(
|
|
Current: Vector = new Vector(0, 0, 0),
|
|
Target: Vector = new Vector(0, 0, 0),
|
|
DeltaTime: Float = 0,
|
|
InterpSpeed: Float = 0
|
|
): Vector {
|
|
return new Vector(
|
|
this.FInterpTo(Current.X, Target.X, DeltaTime, InterpSpeed),
|
|
this.FInterpTo(Current.Y, Target.Y, DeltaTime, InterpSpeed),
|
|
this.FInterpTo(Current.Z, Target.Z, DeltaTime, InterpSpeed)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Normalize a vector to unit length
|
|
* @param A - Input vector
|
|
* @param Tolerance - Minimum length to avoid division by zero
|
|
* @returns Normalized vector (length 1) or zero vector if input is zero
|
|
* @example
|
|
* // Normalize vector (3,4,0)
|
|
* Normalize(new Vector(3,4,0)) // returns Vector(0.6,0.8,0)
|
|
*/
|
|
public Normal(
|
|
A: Vector = new Vector(0, 0, 0),
|
|
Tolerance: Float = 0.0001
|
|
): Vector {
|
|
const length = this.VectorLength(A);
|
|
|
|
if (length > Tolerance) {
|
|
return new Vector(A.X / length, A.Y / length, A.Z / length);
|
|
}
|
|
|
|
return new Vector(0, 0, 0);
|
|
}
|
|
|
|
/**
|
|
* Get the minimum of two float values
|
|
* @param A - First value
|
|
* @param B - Second value
|
|
* @returns Minimum value
|
|
* @example
|
|
* // Minimum of 3 and 5
|
|
* Min(3, 5) // returns 3
|
|
*/
|
|
public Min(A: Float, B: Float): Float {
|
|
return Math.min(A, B);
|
|
}
|
|
|
|
/**
|
|
* Get right vector from roll, pitch, yaw angles
|
|
* @param Roll - Rotation around forward axis in radians
|
|
* @param Pitch - Rotation around right axis in radians
|
|
* @param Yaw - Rotation around up axis in radians
|
|
* @returns Right direction vector
|
|
* @example
|
|
* // Right vector for no rotation
|
|
* GetRightVector(0, 0, 0) // returns Vector(1,0,0)
|
|
*/
|
|
public GetRightVector(
|
|
Roll: Float = 0,
|
|
Pitch: Float = 0,
|
|
Yaw: Float = 0
|
|
): Vector {
|
|
const CP = this.Cos(Pitch);
|
|
const SP = this.Sin(Pitch);
|
|
const CY = this.Cos(Yaw);
|
|
const SY = this.Sin(Yaw);
|
|
|
|
console.log(Roll);
|
|
|
|
return new Vector(CP * CY, CP * SY, SP);
|
|
}
|
|
|
|
/**
|
|
* Get forward vector from roll, pitch, yaw angles
|
|
* @param Roll - Rotation around forward axis in radians
|
|
* @param Pitch - Rotation around right axis in radians
|
|
* @param Yaw - Rotation around up axis in radians
|
|
* @returns Forward direction vector
|
|
* @example
|
|
* // Forward vector for no rotation
|
|
* GetForwardVector(0, 0, 0) // returns Vector(1,0,0)
|
|
*/
|
|
public GetForwardVector(
|
|
Roll: Float = 0,
|
|
Pitch: Float = 0,
|
|
Yaw: Float = 0
|
|
): Vector {
|
|
const CP = this.Cos(Pitch);
|
|
const SP = this.Sin(Pitch);
|
|
const CY = this.Cos(Yaw);
|
|
const SY = this.Sin(Yaw);
|
|
|
|
console.log(Roll);
|
|
|
|
return new Vector(CP * CY, CP * SY, SP);
|
|
}
|
|
|
|
/**
|
|
* Floor a float value to the nearest lower integer
|
|
* @param Value - Input float value
|
|
* @returns Floored integer value
|
|
* @example
|
|
* // Floor 3.7 to 3
|
|
* Floor(3.7) // returns 3
|
|
*/
|
|
public Ceil(Value: Float): Integer {
|
|
return Math.ceil(Value);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Global instance of math library
|
|
* Used throughout the movement system for mathematical calculations
|
|
*/
|
|
export const MathLibrary = new MathLibraryClass();
|