tengri/Content/Movement/Surface/BFL_SurfaceClassifier.ts

124 lines
4.5 KiB
TypeScript

// Movement/Surface/BFL_SurfaceClassifier.ts
import { BFL_Vectors } from '#root/Math/Libraries/BFL_Vectors.ts';
import { E_SurfaceType } from '#root/Movement/Surface/E_SurfaceType.ts';
import type { S_AngleThresholds } from '#root/Movement/Surface/S_AngleThresholds.ts';
import { BlueprintFunctionLibrary } from '#root/UE/BlueprintFunctionLibrary.ts';
import { Vector } from '#root/UE/Vector.ts';
class BFL_SurfaceClassifierClass extends BlueprintFunctionLibrary {
// ════════════════════════════════════════════════════════════════════════════════════════
// CLASSIFICATION
// ════════════════════════════════════════════════════════════════════════════════════════
/**
* Classify surface type based on normal vector and angle thresholds
*
* @param SurfaceNormal - Normalized surface normal vector (from hit result)
* @param AngleThresholdsRads - Angle thresholds in radians (pre-converted for performance)
* @returns Surface type classification
*
* @example
* // Flat ground (normal pointing up)
* const flat = SurfaceClassifier.Classify(new Vector(0, 0, 1), thresholds);
* // Returns: E_SurfaceType.Walkable
*
* @example
* // Steep slope (50° angle)
* const steep = SurfaceClassifier.Classify(BFL_Vectors.GetNormalFromAngle(50), thresholds);
* // Returns: E_SurfaceType.SteepSlope
*
* @pure true
* @category Classification
*/
public Classify(
SurfaceNormal: Vector,
AngleThresholdsRads: S_AngleThresholds
): E_SurfaceType {
// Calculate angle between surface normal and up vector
const surfaceAngle = BFL_Vectors.GetSurfaceAngle(SurfaceNormal);
// Classify based on angle thresholds
if (surfaceAngle <= AngleThresholdsRads.Walkable) {
return E_SurfaceType.Walkable;
} else if (surfaceAngle <= AngleThresholdsRads.SteepSlope) {
return E_SurfaceType.SteepSlope;
} else if (surfaceAngle <= AngleThresholdsRads.Wall) {
return E_SurfaceType.Wall;
} else {
return E_SurfaceType.Ceiling;
}
}
// ════════════════════════════════════════════════════════════════════════════════════════
// TYPE CHECKS
// ════════════════════════════════════════════════════════════════════════════════════════
/**
* Check if surface allows normal walking movement
*
* @param surfaceType - Surface type to check
* @returns True if surface is walkable
*
* @pure true
* @category Type Checks
*/
public IsWalkable(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 Type Checks
*/
public IsSteep(surfaceType: E_SurfaceType): boolean {
return surfaceType === E_SurfaceType.SteepSlope;
}
/**
* Check if surface blocks movement (collision wall)
*
* @param surfaceType - Surface type to check
* @returns True if surface is a wall
*
* @pure true
* @category Type Checks
*/
public IsWall(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 Type Checks
*/
public IsCeiling(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 Type Checks
*/
public IsNone(surfaceType: E_SurfaceType): boolean {
return surfaceType === E_SurfaceType.None;
}
}
export const BFL_SurfaceClassifier = new BFL_SurfaceClassifierClass();