189 lines
6.5 KiB
TypeScript
189 lines
6.5 KiB
TypeScript
// Movement/Components/AC_Movement.ts
|
|
|
|
import { BFL_Vectors } from '#root/Math/Libraries/BFL_Vectors.ts';
|
|
import { E_SurfaceType } from '#root/Movement/Enums/E_SurfaceType.ts';
|
|
import { S_AngleThresholds } from '#root/Movement/Structs/S_AngleThresholds.ts';
|
|
import type { S_MovementConstants } from '#root/Movement/Structs/S_MovementConstants.ts';
|
|
import { ActorComponent } from '#root/UE/ActorComponent.ts';
|
|
import type { Float } from '#root/UE/Float.ts';
|
|
import { MathLibrary } from '#root/UE/MathLibrary.ts';
|
|
import type { Vector } from '#root/UE/Vector.ts';
|
|
|
|
/**
|
|
* Movement System Component
|
|
* Core deterministic movement system for 3D platformer
|
|
* Handles surface classification and movement physics calculations
|
|
*/
|
|
export class AC_Movement extends ActorComponent {
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// FUNCTIONS
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Classify surface type based on normal vector
|
|
* @param SurfaceNormal - Normalized surface normal vector
|
|
* @param AngleThresholds - Angle thresholds in radians
|
|
* @returns Surface type classification
|
|
* @example
|
|
* // Classify flat ground
|
|
* ClassifySurface(new Vector(0,0,1), thresholds) // returns E_SurfaceType.Walkable
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
public ClassifySurface(
|
|
SurfaceNormal: Vector,
|
|
AngleThresholds: S_AngleThresholds
|
|
): E_SurfaceType {
|
|
const SurfaceAngle = BFL_Vectors.GetSurfaceAngle(SurfaceNormal);
|
|
|
|
/**
|
|
* Check if angle is within walkable range
|
|
*/
|
|
const IsWalkableAngle = (walkableAngle: Float): boolean =>
|
|
SurfaceAngle <= walkableAngle;
|
|
|
|
/**
|
|
* Check if angle is within steep slope range
|
|
*/
|
|
const IsSteepSlopeAngle = (steepSlopeAngle: Float): boolean =>
|
|
SurfaceAngle <= steepSlopeAngle;
|
|
|
|
/**
|
|
* Check if angle is within wall range
|
|
*/
|
|
const IsWallAngle = (wallAngle: Float): boolean =>
|
|
SurfaceAngle <= wallAngle;
|
|
|
|
if (IsWalkableAngle(AngleThresholds.Walkable)) {
|
|
return E_SurfaceType.Walkable;
|
|
} else if (IsSteepSlopeAngle(AngleThresholds.SteepSlope)) {
|
|
return E_SurfaceType.SteepSlope;
|
|
} else if (IsWallAngle(AngleThresholds.Wall)) {
|
|
return E_SurfaceType.Wall;
|
|
} else {
|
|
return E_SurfaceType.Ceiling;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if surface allows normal walking movement
|
|
* @param SurfaceType - Surface type to check
|
|
* @returns True if surface is walkable
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
private IsSurfaceWalkable(SurfaceType: E_SurfaceType): boolean {
|
|
return SurfaceType === E_SurfaceType.Walkable;
|
|
}
|
|
|
|
/**
|
|
* Check if surface causes sliding behavior
|
|
* @param SurfaceType - Surface type to check
|
|
* @returns True if surface is steep slope
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
private IsSurfaceSteep(SurfaceType: E_SurfaceType): boolean {
|
|
return SurfaceType === E_SurfaceType.SteepSlope;
|
|
}
|
|
|
|
/**
|
|
* Check if surface blocks movement (collision)
|
|
* @param SurfaceType - Surface type to check
|
|
* @returns True if surface is a wall
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
private IsSurfaceWall(SurfaceType: E_SurfaceType): boolean {
|
|
return SurfaceType === E_SurfaceType.Wall;
|
|
}
|
|
|
|
/**
|
|
* Check if surface is overhead (ceiling)
|
|
* @param SurfaceType - Surface type to check
|
|
* @returns True if surface is ceiling
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
private IsSurfaceCeiling(SurfaceType: E_SurfaceType): boolean {
|
|
return SurfaceType === E_SurfaceType.Ceiling;
|
|
}
|
|
|
|
/**
|
|
* Check if no surface detected (airborne state)
|
|
* @param SurfaceType - Surface type to check
|
|
* @returns True if no surface contact
|
|
* @pure true
|
|
* @category Surface Detection
|
|
*/
|
|
private IsSurfaceNone(SurfaceType: E_SurfaceType): boolean {
|
|
return SurfaceType === E_SurfaceType.None;
|
|
}
|
|
|
|
/**
|
|
* Initialize movement system with angle conversion
|
|
* Converts degree thresholds to radians for runtime performance
|
|
* @category System
|
|
*/
|
|
public InitializeMovementSystem(): void {
|
|
this.IsInitialized = true;
|
|
|
|
this.AngleThresholdsRads = {
|
|
Walkable: MathLibrary.DegreesToRadians(
|
|
this.AngleThresholdsDegrees.Walkable
|
|
),
|
|
SteepSlope: MathLibrary.DegreesToRadians(
|
|
this.AngleThresholdsDegrees.SteepSlope
|
|
),
|
|
Wall: MathLibrary.DegreesToRadians(this.AngleThresholdsDegrees.Wall),
|
|
};
|
|
}
|
|
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
// VARIABLES
|
|
// ════════════════════════════════════════════════════════════════════════════════════════
|
|
|
|
/**
|
|
* Movement physics constants
|
|
* Controls speed, acceleration, friction, and gravity values
|
|
* @category Movement Config
|
|
* @instanceEditable true
|
|
*/
|
|
public readonly MovementConstants: S_MovementConstants = {
|
|
MaxSpeed: 600.0,
|
|
Acceleration: 2000.0,
|
|
Friction: 8.0,
|
|
Gravity: 980.0,
|
|
};
|
|
|
|
/**
|
|
* Surface classification angle thresholds in degrees
|
|
* Walkable ≤50°, SteepSlope ≤85°, Wall ≤95°, Ceiling >95°
|
|
* @category Movement Config
|
|
* @instanceEditable true
|
|
*/
|
|
public readonly AngleThresholdsDegrees: S_AngleThresholds = {
|
|
Walkable: 50.0,
|
|
SteepSlope: 85.0,
|
|
Wall: 95.0,
|
|
};
|
|
|
|
/**
|
|
* Runtime cached angle thresholds in radians
|
|
* Converted from degrees during initialization for performance
|
|
* @category Internal Cache
|
|
*/
|
|
private AngleThresholdsRads: S_AngleThresholds = {
|
|
Walkable: 0.0,
|
|
SteepSlope: 0.0,
|
|
Wall: 0.0,
|
|
};
|
|
|
|
/**
|
|
* Flag indicating if movement system has been initialized
|
|
* Ensures angle thresholds are converted before use
|
|
* @category Debug
|
|
*/
|
|
public IsInitialized = false;
|
|
}
|