Refactor; Optimize simulation
This commit is contained in:
parent
8581cf6fb8
commit
0ef5652cea
16 changed files with 508 additions and 651 deletions
|
|
@ -1,332 +1,295 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
public abstract class GameObject
|
||||
{
|
||||
[Flags]
|
||||
public enum DirtyFlags : ulong
|
||||
{
|
||||
None = 0,
|
||||
UUID = 1UL << 0,
|
||||
Sector = 1UL << 1,
|
||||
LocalCoordinates = 1UL << 2,
|
||||
Rotation = 1UL << 3,
|
||||
Velocity = 1UL << 4,
|
||||
AngularVelocity = 1UL << 5
|
||||
}
|
||||
public DirtyFlags DirtyBits { get; protected set; } = DirtyFlags.None;
|
||||
[Flags]
|
||||
public enum DirtyFlags : ulong
|
||||
{
|
||||
None = 0,
|
||||
UUID = 1UL << 0,
|
||||
Sector = 1UL << 1,
|
||||
LocalCoordinates = 1UL << 2,
|
||||
Rotation = 1UL << 3,
|
||||
Velocity = 1UL << 4,
|
||||
AngularVelocity = 1UL << 5
|
||||
}
|
||||
public DirtyFlags DirtyBits { get; protected set; } = DirtyFlags.None;
|
||||
|
||||
protected Guid _uuid;
|
||||
public Guid UUID
|
||||
{
|
||||
get => _uuid;
|
||||
set
|
||||
{
|
||||
if (_uuid != value)
|
||||
{
|
||||
_uuid = value;
|
||||
DirtyBits |= DirtyFlags.UUID;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Guid _uuid;
|
||||
public Guid UUID
|
||||
{
|
||||
get => _uuid;
|
||||
set
|
||||
{
|
||||
if (_uuid != value)
|
||||
{
|
||||
_uuid = value;
|
||||
DirtyBits |= DirtyFlags.UUID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3I _currentSectorCoordinates;
|
||||
protected Sector _currentSector;
|
||||
public Sector CurrentSector
|
||||
{
|
||||
get => _currentSector;
|
||||
protected set
|
||||
{
|
||||
if (_currentSector != value)
|
||||
{
|
||||
_currentSector = value;
|
||||
_currentSectorCoordinates = value.Coordinates;
|
||||
DirtyBits |= DirtyFlags.Sector;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Vector3I _currentSectorCoordinates;
|
||||
protected Sector _currentSector;
|
||||
public Sector CurrentSector
|
||||
{
|
||||
get => _currentSector;
|
||||
protected set
|
||||
{
|
||||
if (_currentSector != value)
|
||||
{
|
||||
_currentSector = value;
|
||||
_currentSectorCoordinates = value.Coordinates;
|
||||
DirtyBits |= DirtyFlags.Sector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3 _localCoordinates;
|
||||
public Vector3 LocalCoordinates
|
||||
{
|
||||
get => _localCoordinates;
|
||||
protected set
|
||||
{
|
||||
if (_localCoordinates != value)
|
||||
{
|
||||
_localCoordinates = value;
|
||||
DirtyBits |= DirtyFlags.LocalCoordinates;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Vector3 _localCoordinates;
|
||||
public Vector3 LocalCoordinates
|
||||
{
|
||||
get => _localCoordinates;
|
||||
protected set
|
||||
{
|
||||
if (_localCoordinates != value)
|
||||
{
|
||||
_localCoordinates = value;
|
||||
DirtyBits |= DirtyFlags.LocalCoordinates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3 _rotation;
|
||||
public Vector3 Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
protected set
|
||||
{
|
||||
if (_rotation != value)
|
||||
{
|
||||
_rotation = value;
|
||||
DirtyBits |= DirtyFlags.Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Vector3 _rotation;
|
||||
public Vector3 Rotation
|
||||
{
|
||||
get => _rotation;
|
||||
protected set
|
||||
{
|
||||
if (_rotation != value)
|
||||
{
|
||||
_rotation = value;
|
||||
DirtyBits |= DirtyFlags.Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3 _velocity;
|
||||
public Vector3 Velocity
|
||||
{
|
||||
get => _velocity;
|
||||
protected set
|
||||
{
|
||||
if (_velocity != value)
|
||||
{
|
||||
_velocity = value;
|
||||
DirtyBits |= DirtyFlags.Velocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Vector3 _velocity;
|
||||
public Vector3 Velocity
|
||||
{
|
||||
get => _velocity;
|
||||
protected set
|
||||
{
|
||||
if (_velocity != value)
|
||||
{
|
||||
_velocity = value;
|
||||
DirtyBits |= DirtyFlags.Velocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector3 _angularVelocity;
|
||||
public Vector3 AngularVelocity
|
||||
{
|
||||
get => _angularVelocity;
|
||||
protected set
|
||||
{
|
||||
if (_angularVelocity != value)
|
||||
{
|
||||
_angularVelocity = value;
|
||||
DirtyBits |= DirtyFlags.AngularVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected Vector3 _angularVelocity;
|
||||
public Vector3 AngularVelocity
|
||||
{
|
||||
get => _angularVelocity;
|
||||
protected set
|
||||
{
|
||||
if (_angularVelocity != value)
|
||||
{
|
||||
_angularVelocity = value;
|
||||
DirtyBits |= DirtyFlags.AngularVelocity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3Dec GlobalCoordinates { get; protected set; }
|
||||
public Vector3 SectorOffset { get; protected set; }
|
||||
public Vector3 SectorOffset { get; protected set; }
|
||||
|
||||
protected bool reassigning = false;
|
||||
protected bool reassigning = false;
|
||||
|
||||
public GameObject(Sector sector, Vector3 localCoordinates)
|
||||
{
|
||||
UUID = Guid.NewGuid();
|
||||
public GameObject(Sector sector, Vector3 localCoordinates)
|
||||
{
|
||||
UUID = Guid.NewGuid();
|
||||
|
||||
CurrentSector = sector;
|
||||
LocalCoordinates = localCoordinates;
|
||||
CurrentSector = sector;
|
||||
LocalCoordinates = localCoordinates;
|
||||
|
||||
Velocity = new(0, 0, 1);
|
||||
AngularVelocity = Vector3.Zero;
|
||||
Rotation = Vector3.Zero;
|
||||
Velocity = new(0, 0, 1);
|
||||
AngularVelocity = Vector3.Zero;
|
||||
Rotation = Vector3.Zero;
|
||||
}
|
||||
|
||||
GlobalCoordinates = CalculateGlobalCoordinates(sector.GlobalCenterCoordinates, localCoordinates);
|
||||
}
|
||||
public void ApplyVelocity(double delta)
|
||||
{
|
||||
SetCoordinates(LocalCoordinates + Velocity * delta);
|
||||
Rotation += AngularVelocity * delta;
|
||||
}
|
||||
|
||||
public GameObject(Vector3Dec coordinates)
|
||||
{
|
||||
GlobalCoordinates = coordinates;
|
||||
UpdateSector();
|
||||
}
|
||||
public bool IsInCurrentSector()
|
||||
{
|
||||
return Helpers.IsInsideArea(GameManager.Generator.GetSectorSize() / 2, LocalCoordinates);
|
||||
}
|
||||
|
||||
public GameObject(decimal x, decimal y, decimal z)
|
||||
{
|
||||
GlobalCoordinates = new(x, y, z);
|
||||
UpdateSector();
|
||||
}
|
||||
public void UpdateSector()
|
||||
{
|
||||
if (!GameManager.GameUniverse.IsInside(CurrentSector.Coordinates, LocalCoordinates))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public Vector3Dec CalculateGlobalCoordinates(Vector3Dec sectorCenter, Vector3 local)
|
||||
{
|
||||
return new
|
||||
(
|
||||
sectorCenter.X + (decimal)local.X,
|
||||
sectorCenter.Y + (decimal)local.Y,
|
||||
sectorCenter.Z + (decimal)local.Z
|
||||
);
|
||||
}
|
||||
Vector3 sectorSize = GameManager.Generator.GetSectorSize() / 2;
|
||||
|
||||
public void ApplyVelocity(double delta)
|
||||
{
|
||||
SetCoordinatesFromLocal(LocalCoordinates + Velocity * delta);
|
||||
Rotation += AngularVelocity * delta;
|
||||
}
|
||||
bool? x = null;
|
||||
bool? y = null;
|
||||
bool? z = null;
|
||||
|
||||
public bool IsInCurrentSector()
|
||||
{
|
||||
return Helpers.IsInsideArea(CurrentSector.Size / 2, LocalCoordinates);
|
||||
}
|
||||
if (LocalCoordinates.X > sectorSize.X) x = true;
|
||||
else if (LocalCoordinates.X < -sectorSize.X) x = false;
|
||||
|
||||
public void UpdateSector()
|
||||
{
|
||||
List<Sector> neighbours = CurrentSector.GetNeighbouringSectors();
|
||||
foreach (Sector sector in neighbours)
|
||||
{
|
||||
if (sector.IsObjectInSector(this))
|
||||
{
|
||||
reassigning = true;
|
||||
sector.AssignObject(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (LocalCoordinates.Y > sectorSize.Y) y = true;
|
||||
else if (LocalCoordinates.Y < -sectorSize.Y) y = false;
|
||||
|
||||
if (!GameManager.GameUniverse.IsInside(CurrentSector.Coordinates, LocalCoordinates))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (LocalCoordinates.Z > sectorSize.Z) z = true;
|
||||
else if (LocalCoordinates.Z < -sectorSize.Z) z = false;
|
||||
|
||||
foreach (Sector sector in GameManager.GameUniverse.Sectors)
|
||||
{
|
||||
if (sector.IsObjectInSector(this))
|
||||
{
|
||||
reassigning = true;
|
||||
sector.AssignObject(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Sector sector = GameManager.GameUniverse.GetNeighbouringSector(CurrentSector, x, y, z);
|
||||
if (sector != null)
|
||||
{
|
||||
reassigning = true;
|
||||
sector.AssignObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AssignSector(Sector sector)
|
||||
{
|
||||
CurrentSector = sector;
|
||||
ResetLocalCoordinates();
|
||||
public virtual void AssignSector(Sector sector)
|
||||
{
|
||||
Vector3 sectorOffset = GetSectorOffset(sector);
|
||||
|
||||
UpdateSectorOffsetToMainPlayer();
|
||||
CurrentSector = sector;
|
||||
LocalCoordinates += sectorOffset;
|
||||
|
||||
List<Sector> neighbours = GameManager.Instance.GetCurrentSector().GetNeighbouringSectors();
|
||||
UpdateSectorOffsetToMainPlayer();
|
||||
|
||||
if (neighbours.Contains(sector))
|
||||
{
|
||||
GameManager.Instance.Spawn(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameManager.Instance.Despawn(this);
|
||||
}
|
||||
reassigning = false;
|
||||
}
|
||||
|
||||
reassigning = false;
|
||||
}
|
||||
public Vector3 GetSectorOffset(Sector sector)
|
||||
{
|
||||
Vector3I relative = CurrentSector.Coordinates - sector.Coordinates;
|
||||
return relative * GameManager.Generator.GetSectorSize();
|
||||
}
|
||||
|
||||
public Vector3 GetSectorOffset(Sector sector)
|
||||
{
|
||||
Vector3Dec relative = CurrentSector.GlobalCenterCoordinates - sector.GlobalCenterCoordinates;
|
||||
return relative.ToVector3();
|
||||
}
|
||||
public void UpdateSectorOffset(Sector sector)
|
||||
{
|
||||
SectorOffset = GetSectorOffset(sector);
|
||||
}
|
||||
|
||||
public void UpdateSectorOffset(Sector sector)
|
||||
{
|
||||
SectorOffset = GetSectorOffset(sector);
|
||||
}
|
||||
public void UpdateSectorOffsetToMainPlayer()
|
||||
{
|
||||
UpdateSectorOffset(GameManager.Instance.GetCurrentSector());
|
||||
}
|
||||
|
||||
public void UpdateSectorOffsetToMainPlayer()
|
||||
{
|
||||
UpdateSectorOffset(GameManager.Instance.GetCurrentSector());
|
||||
}
|
||||
public void SetCoordinates(Vector3 localCoordinates)
|
||||
{
|
||||
LocalCoordinates = localCoordinates;
|
||||
|
||||
public void SetCoordinatesFromGlobal(Vector3Dec globalCoordinates)
|
||||
{
|
||||
GlobalCoordinates = globalCoordinates;
|
||||
LocalCoordinates = (globalCoordinates - CurrentSector.GlobalCenterCoordinates).ToVector3();
|
||||
UpdateNodePosition();
|
||||
}
|
||||
|
||||
UpdateNodePosition();
|
||||
}
|
||||
public double GetDistanceToObject(GameObject gameObject)
|
||||
{
|
||||
Sector sector = gameObject.CurrentSector;
|
||||
Vector3 sectorOffset = GetSectorOffset(sector);
|
||||
|
||||
public void SetCoordinatesFromLocal(Vector3 localCoordinates)
|
||||
{
|
||||
LocalCoordinates = localCoordinates;
|
||||
GlobalCoordinates = Vector3Dec.FromVector3(localCoordinates) + CurrentSector.GlobalCenterCoordinates;
|
||||
Vector3 position1 = LocalCoordinates;
|
||||
Vector3 position2 = gameObject.LocalCoordinates - sectorOffset;
|
||||
|
||||
UpdateNodePosition();
|
||||
}
|
||||
return Helpers.GetDistance(position1, position2);
|
||||
}
|
||||
|
||||
public void ResetLocalCoordinates()
|
||||
{
|
||||
SetCoordinatesFromGlobal(GlobalCoordinates);
|
||||
}
|
||||
public virtual void UpdateNodePosition() { }
|
||||
|
||||
public virtual void UpdateNodePosition() { }
|
||||
public virtual void Simulate(double delta)
|
||||
{
|
||||
ApplyVelocity(delta);
|
||||
|
||||
public virtual void Simulate(double delta)
|
||||
{
|
||||
ApplyVelocity(delta);
|
||||
if (!reassigning && !IsInCurrentSector())
|
||||
{
|
||||
UpdateSector();
|
||||
}
|
||||
}
|
||||
|
||||
if (!reassigning && !IsInCurrentSector())
|
||||
{
|
||||
UpdateSector();
|
||||
}
|
||||
}
|
||||
public virtual Node3D Instantiate(Sector sector)
|
||||
{
|
||||
PackedScene modulePrefab = ResourceLoader.Load<PackedScene>("res://prefabs/gameObjects/node.tscn");
|
||||
Node3D instance = modulePrefab.Instantiate<Node3D>();
|
||||
|
||||
public virtual Node3D Instantiate(Sector sector)
|
||||
{
|
||||
PackedScene modulePrefab = ResourceLoader.Load<PackedScene>("res://prefabs/gameObjects/node.tscn");
|
||||
Node3D instance = modulePrefab.Instantiate<Node3D>();
|
||||
instance.Name = $"GameObject-{UUID}";
|
||||
|
||||
instance.Name = $"GameObject-{UUID}";
|
||||
return instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
public virtual Godot.Collections.Dictionary NetworkWrite(long id, bool full)
|
||||
{
|
||||
Godot.Collections.Dictionary gameObjectData = [];
|
||||
|
||||
public virtual Godot.Collections.Dictionary NetworkWrite(long id, bool full)
|
||||
{
|
||||
Godot.Collections.Dictionary gameObjectData = [];
|
||||
if (full)
|
||||
gameObjectData.Add("type", GetType().ToString());
|
||||
|
||||
if (full)
|
||||
gameObjectData.Add("type", GetType().ToString());
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Sector) || full)
|
||||
gameObjectData.Add("sectorCoordinates", _currentSectorCoordinates);
|
||||
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Sector) || full)
|
||||
gameObjectData.Add("sectorCoordinates", _currentSectorCoordinates);
|
||||
if (DirtyBits.HasFlag(DirtyFlags.LocalCoordinates) || full)
|
||||
gameObjectData.Add("localCoordinates", _localCoordinates);
|
||||
|
||||
if (DirtyBits.HasFlag(DirtyFlags.LocalCoordinates) || full)
|
||||
gameObjectData.Add("localCoordinates", _localCoordinates);
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Rotation) || full)
|
||||
gameObjectData.Add("rotation", _rotation);
|
||||
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Rotation) || full)
|
||||
gameObjectData.Add("rotation", _rotation);
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Velocity) || full)
|
||||
gameObjectData.Add("velocity", _velocity);
|
||||
|
||||
if (DirtyBits.HasFlag(DirtyFlags.Velocity) || full)
|
||||
gameObjectData.Add("velocity", _velocity);
|
||||
if (DirtyBits.HasFlag(DirtyFlags.AngularVelocity) || full)
|
||||
gameObjectData.Add("angularVelocity", _angularVelocity);
|
||||
|
||||
if (DirtyBits.HasFlag(DirtyFlags.AngularVelocity) || full)
|
||||
gameObjectData.Add("angularVelocity", _angularVelocity);
|
||||
if (gameObjectData.Count > 0)
|
||||
{
|
||||
gameObjectData.Add("uuid", UUID.ToString());
|
||||
return gameObjectData;
|
||||
}
|
||||
|
||||
if (gameObjectData.Count > 0)
|
||||
{
|
||||
gameObjectData.Add("uuid", UUID.ToString());
|
||||
return gameObjectData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public virtual void NetworkRead(Godot.Collections.Dictionary gameObjectData)
|
||||
{
|
||||
if (gameObjectData.TryGetValue("sectorCoordinates", out var sectorCoordinatesData))
|
||||
{
|
||||
Sector newSector = GameManager.GameUniverse.GetSector((Vector3I)sectorCoordinatesData);
|
||||
CurrentSector.GameObjects.Remove(this);
|
||||
newSector.GameObjects.Add(this);
|
||||
|
||||
public virtual void NetworkRead(Godot.Collections.Dictionary gameObjectData)
|
||||
{
|
||||
if (gameObjectData.TryGetValue("sectorCoordinates", out var sectorCoordinatesData))
|
||||
{
|
||||
Sector newSector = GameManager.GameUniverse.GetSector((Vector3I)sectorCoordinatesData);
|
||||
CurrentSector.GameObjects.Remove(this);
|
||||
newSector.GameObjects.Add(this);
|
||||
AssignSector(newSector);
|
||||
}
|
||||
|
||||
AssignSector(newSector);
|
||||
}
|
||||
if (gameObjectData.TryGetValue("localCoordinates", out var localCoordinatesData))
|
||||
LocalCoordinates = (Vector3)localCoordinatesData;
|
||||
|
||||
if (gameObjectData.TryGetValue("localCoordinates", out var localCoordinatesData))
|
||||
LocalCoordinates = (Vector3)localCoordinatesData;
|
||||
if (gameObjectData.TryGetValue("rotation", out var rotationData))
|
||||
Rotation = (Vector3)rotationData;
|
||||
|
||||
if (gameObjectData.TryGetValue("rotation", out var rotationData))
|
||||
Rotation = (Vector3)rotationData;
|
||||
if (gameObjectData.TryGetValue("velocity", out var velocityData))
|
||||
Velocity = (Vector3)velocityData;
|
||||
|
||||
if (gameObjectData.TryGetValue("velocity", out var velocityData))
|
||||
Velocity = (Vector3)velocityData;
|
||||
if (gameObjectData.TryGetValue("angularVelocity", out var angularVelocityData))
|
||||
AngularVelocity = (Vector3)angularVelocityData;
|
||||
}
|
||||
|
||||
if (gameObjectData.TryGetValue("angularVelocity", out var angularVelocityData))
|
||||
AngularVelocity = (Vector3)angularVelocityData;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
GameObject gameObj = (GameObject)obj;
|
||||
return gameObj.UUID == UUID;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
GameObject gameObj = (GameObject)obj;
|
||||
return gameObj.UUID == UUID;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UUID.GetHashCode();
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UUID.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue