SIMD-accelerated gas mixtures. (SIMD atmos) (#2479)
* SIMD atmos * Moles will always be a multiple of four. * Component dependencies for grid atmos. * Let's optimize allocations while we're at it! * Inline this * A bunch of atmos optimizations * Fix crimes against atmos * Microsoft moment * Remove nuget.config * do not reference Robust.UnitTests in Content.Benchmarks as it's unneeded. * Revert "Remove nuget.config" This reverts commit 872604ae6a51365af4075bb23687bd005befd8ac. * Gas overlay optimization and fixes * Lattice is now spess * minor atmos tweaks
This commit is contained in:
committed by
GitHub
parent
89f72c4cb2
commit
b18ee3ec49
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
@@ -135,6 +136,12 @@ namespace Content.Shared.Atmos
|
||||
{
|
||||
return direction & ~other;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsFlagSet(this AtmosDirection direction, AtmosDirection other)
|
||||
{
|
||||
return (direction & other) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AtmosDirectionFlags { }
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Content.Shared.Construction.ConstructionConditions
|
||||
if (tileFound == null)
|
||||
return false;
|
||||
|
||||
var tile = TurfHelpers.GetContentTileDefinition(tileFound.Value.Tile);
|
||||
var tile = tileFound.Value.Tile.GetContentTileDefinition();
|
||||
foreach (var targetTile in TargetTiles)
|
||||
{
|
||||
if (tile.Name == targetTile) {
|
||||
|
||||
@@ -11,9 +11,9 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private readonly GasPrototype[] GasPrototypes = new GasPrototype[Atmospherics.TotalNumberOfGases];
|
||||
protected readonly GasPrototype[] GasPrototypes = new GasPrototype[Atmospherics.TotalNumberOfGases];
|
||||
|
||||
private readonly SpriteSpecifier[] GasOverlays = new SpriteSpecifier[Atmospherics.TotalNumberOfGases];
|
||||
private readonly SpriteSpecifier[] _gasOverlays = new SpriteSpecifier[Atmospherics.TotalNumberOfGases];
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -25,10 +25,10 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos
|
||||
GasPrototypes[i] = gasPrototype;
|
||||
|
||||
if(string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayTexture))
|
||||
GasOverlays[i] = new SpriteSpecifier.Texture(new ResourcePath(gasPrototype.GasOverlayTexture));
|
||||
_gasOverlays[i] = new SpriteSpecifier.Texture(new ResourcePath(gasPrototype.GasOverlayTexture));
|
||||
|
||||
if(!string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayState))
|
||||
GasOverlays[i] = new SpriteSpecifier.Rsi(new ResourcePath(gasPrototype.GasOverlaySprite), gasPrototype.GasOverlayState);
|
||||
_gasOverlays[i] = new SpriteSpecifier.Rsi(new ResourcePath(gasPrototype.GasOverlaySprite), gasPrototype.GasOverlayState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,6 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos
|
||||
|
||||
public IEnumerable<GasPrototype> Gases => GasPrototypes;
|
||||
|
||||
public SpriteSpecifier GetOverlay(int overlayId) => GasOverlays[overlayId];
|
||||
public SpriteSpecifier GetOverlay(int overlayId) => _gasOverlays[overlayId];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,26 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public struct GasData
|
||||
public readonly struct GasData : IEquatable<GasData>
|
||||
{
|
||||
public byte Index { get; set; }
|
||||
public byte Opacity { get; set; }
|
||||
public readonly byte Index;
|
||||
public readonly byte Opacity;
|
||||
|
||||
public GasData(byte gasId, byte opacity)
|
||||
{
|
||||
Index = gasId;
|
||||
Opacity = opacity;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Index, Opacity);
|
||||
}
|
||||
|
||||
public bool Equals(GasData other)
|
||||
{
|
||||
return other.Index == Index && other.Opacity == Opacity;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
@@ -38,39 +48,48 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos
|
||||
public readonly byte FireState;
|
||||
public readonly float FireTemperature;
|
||||
public readonly GasData[] Gas;
|
||||
public readonly int HashCode;
|
||||
|
||||
public GasOverlayData(byte fireState, float fireTemperature, GasData[] gas)
|
||||
{
|
||||
FireState = fireState;
|
||||
FireTemperature = fireTemperature;
|
||||
Gas = gas;
|
||||
Gas = gas ?? Array.Empty<GasData>();
|
||||
|
||||
Array.Sort(Gas, (a, b) => a.Index.CompareTo(b.Index));
|
||||
|
||||
var hash = new HashCode();
|
||||
hash.Add(FireState);
|
||||
hash.Add(FireTemperature);
|
||||
|
||||
foreach (var gasData in Gas)
|
||||
{
|
||||
hash.Add(gasData);
|
||||
}
|
||||
|
||||
HashCode = hash.ToHashCode();
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode;
|
||||
}
|
||||
|
||||
public bool Equals(GasOverlayData other)
|
||||
{
|
||||
// TODO: Moony had a suggestion on how to do this faster with the hash
|
||||
// https://discordapp.com/channels/310555209753690112/310555209753690112/744080145219846204
|
||||
// Aside from that I can't really see any low-hanging fruit CPU perf wise.
|
||||
if (Gas?.Length != other.Gas?.Length) return false;
|
||||
|
||||
if (HashCode != other.HashCode) return false;
|
||||
if (Gas.Length != other.Gas.Length) return false;
|
||||
if (FireState != other.FireState) return false;
|
||||
if (FireTemperature != other.FireTemperature) return false;
|
||||
|
||||
if (Gas == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DebugTools.Assert(other.Gas != null);
|
||||
if (MathHelper.CloseTo(FireTemperature, FireTemperature)) return false;
|
||||
if (Gas.GetHashCode() != other.Gas.GetHashCode()) return false;
|
||||
|
||||
for (var i = 0; i < Gas.Length; i++)
|
||||
{
|
||||
var thisGas = Gas[i];
|
||||
var gas = Gas[i];
|
||||
var otherGas = other.Gas[i];
|
||||
|
||||
if (!thisGas.Equals(otherGas))
|
||||
{
|
||||
if (!gas.Equals(otherGas))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace Content.Shared.Maps
|
||||
public float Friction { get; set; }
|
||||
public float ThermalConductivity { get; set; }
|
||||
public string ItemDropPrototypeName { get; private set; }
|
||||
public bool IsSpace { get; private set; }
|
||||
|
||||
public void AssignTileId(ushort id)
|
||||
{
|
||||
@@ -47,6 +48,11 @@ namespace Content.Shared.Maps
|
||||
else
|
||||
BaseTurfs = new List<string>();
|
||||
|
||||
if (mapping.TryGetNode("is_space", out node))
|
||||
{
|
||||
IsSpace = node.AsBool();
|
||||
}
|
||||
|
||||
if (mapping.TryGetNode("can_crowbar", out node))
|
||||
{
|
||||
CanCrowbar = node.AsBool();
|
||||
|
||||
@@ -9,6 +9,7 @@ using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Interfaces.Physics;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
@@ -16,15 +17,6 @@ namespace Content.Shared.Maps
|
||||
{
|
||||
public static class TurfHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the content tile definition for a tile.
|
||||
/// </summary>
|
||||
public static ContentTileDefinition GetContentTileDefinition(this Tile tile)
|
||||
{
|
||||
var tileDefinitionManager = IoCManager.Resolve<ITileDefinitionManager>();
|
||||
return (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the turf at map indices with grid id or null if no such turf is found.
|
||||
/// </summary>
|
||||
@@ -72,6 +64,39 @@ namespace Content.Shared.Maps
|
||||
return (turf = coordinates.GetTileRef()) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the content tile definition for a tile.
|
||||
/// </summary>
|
||||
public static ContentTileDefinition GetContentTileDefinition(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null)
|
||||
{
|
||||
tileDefinitionManager ??= IoCManager.Resolve<ITileDefinitionManager>();
|
||||
return (ContentTileDefinition)tileDefinitionManager[tile.TypeId];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a tile is considered space.
|
||||
/// </summary>
|
||||
public static bool IsSpace(this Tile tile, ITileDefinitionManager? tileDefinitionManager = null)
|
||||
{
|
||||
return tile.GetContentTileDefinition(tileDefinitionManager).IsSpace;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the content tile definition for a tile ref.
|
||||
/// </summary>
|
||||
public static ContentTileDefinition GetContentTileDefinition(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null)
|
||||
{
|
||||
return tile.Tile.GetContentTileDefinition(tileDefinitionManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a tile ref is considered space.
|
||||
/// </summary>
|
||||
public static bool IsSpace(this TileRef tile, ITileDefinitionManager? tileDefinitionManager = null)
|
||||
{
|
||||
return tile.Tile.IsSpace(tileDefinitionManager);
|
||||
}
|
||||
|
||||
public static bool PryTile(this EntityCoordinates coordinates, IEntityManager? entityManager = null,
|
||||
IMapManager? mapManager = null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user