using System.Numerics;
using AcDream.App.World;
using AcDream.Core.Physics;
using AcDream.Core.Physics.Motion;
using AcDream.Runtime.Physics;
namespace AcDream.App.Physics;
///
/// Graphical configuration factory for Runtime's presentation-free
/// . Runtime owns exact-incarnation
/// installation, stable identity, manager lifetime, and lookup.
///
internal static class EntityPhysicsHostComposition
{
internal static EntityPhysicsHost InstallOrRebind(
LiveEntityRuntime runtime,
LiveEntityRecord expectedRecord,
EntityPhysicsHost configuration)
{
ArgumentNullException.ThrowIfNull(runtime);
ArgumentNullException.ThrowIfNull(expectedRecord);
ArgumentNullException.ThrowIfNull(configuration);
bool ProjectionIsCurrent() =>
runtime.TryGetRecord(
expectedRecord.ServerGuid,
out LiveEntityRecord current)
&& ReferenceEquals(current, expectedRecord);
return runtime.Physics.InstallOrRebindPhysicsHost(
expectedRecord.Canonical,
configuration,
ProjectionIsCurrent);
}
internal static EntityPhysicsHost SelectStableHostWithoutRebind(
LiveEntityRuntime runtime,
LiveEntityRecord expectedRecord,
EntityPhysicsHost configuration)
{
ArgumentNullException.ThrowIfNull(runtime);
ArgumentNullException.ThrowIfNull(expectedRecord);
ArgumentNullException.ThrowIfNull(configuration);
bool ProjectionIsCurrent() =>
runtime.TryGetRecord(
expectedRecord.ServerGuid,
out LiveEntityRecord current)
&& ReferenceEquals(current, expectedRecord);
return runtime.Physics.SelectStablePhysicsHostWithoutRebind(
expectedRecord.Canonical,
configuration,
ProjectionIsCurrent);
}
internal static EntityPhysicsHost CreateMinimal(
LiveEntityRecord record,
Func resolve,
Func now)
{
ArgumentNullException.ThrowIfNull(record);
ArgumentNullException.ThrowIfNull(resolve);
ArgumentNullException.ThrowIfNull(now);
return new EntityPhysicsHost(
record.ServerGuid,
getPosition: () => new Position(
record.FullCellId,
record.WorldEntity?.Position
?? record.PhysicsBody?.Position
?? Vector3.Zero,
record.WorldEntity?.Rotation
?? record.PhysicsBody?.Orientation
?? Quaternion.Identity),
getVelocity: () => record.PhysicsBody?.Velocity ?? Vector3.Zero,
getRadius: () => 0f,
inContact: () => record.PhysicsBody?.InContact ?? true,
minterpMaxSpeed: () => null,
curTime: now,
physicsTimerTime: now,
getObjectA: resolve,
handleUpdateTarget: _ => { },
interruptCurrentMovement: () => { });
}
}