Performance Optimization
Asteroid positioning is now multithreaded Item quality calculation is now allocation free Various other garbage reductions
This commit is contained in:
parent
cf74519cd9
commit
8d6770ab15
21 changed files with 151 additions and 72 deletions
|
|
@ -55,10 +55,10 @@ public class MiningTool : IBehavior
|
|||
public bool Execute(float delta)
|
||||
{
|
||||
Range = Context.Evaluate(_data.Range, Item.EquippableItem, Entity);
|
||||
var asteroidTransform = Entity.Zone.GetAsteroidTransform(AsteroidBelt, Asteroid);
|
||||
var belt = Entity.Zone.AsteroidBelts[AsteroidBelt];
|
||||
if (AsteroidBelt != Guid.Empty &&
|
||||
Entity.Zone.AsteroidExists(AsteroidBelt, Asteroid) &&
|
||||
length(Entity.Position.xz - asteroidTransform.xz) - asteroidTransform.w < Range)
|
||||
length(Entity.Position.xz - belt.Positions[Asteroid].xz) - belt.Scales[Asteroid] < Range)
|
||||
{
|
||||
Entity.Zone.MineAsteroid(
|
||||
Entity,
|
||||
|
|
|
|||
|
|
@ -75,18 +75,21 @@ public class Reactor : IBehavior, IOrderedBehavior
|
|||
// We have an energy deficit, try to get some energy out of our capacitors first
|
||||
if (Entity.Energy < 0)
|
||||
{
|
||||
Capacitor[] chargedCapacitors;
|
||||
int chargedCapacitors = 0;
|
||||
do
|
||||
{
|
||||
var chargeToRemove = -Entity.Energy;
|
||||
chargedCapacitors = _capacitors.Where(x => x.Charge > 0.01f).ToArray();
|
||||
foreach (var cap in chargedCapacitors)
|
||||
foreach (var cap in _capacitors)
|
||||
{
|
||||
var chargeRemoved = min(chargeToRemove / chargedCapacitors.Length, cap.Charge);
|
||||
cap.AddCharge(-chargeRemoved);
|
||||
Entity.Energy += chargeRemoved;
|
||||
if(cap.Charge > 0.01f)
|
||||
{
|
||||
chargedCapacitors++;
|
||||
var chargeRemoved = min(chargeToRemove / chargedCapacitors, cap.Charge);
|
||||
cap.AddCharge(-chargeRemoved);
|
||||
Entity.Energy += chargeRemoved;
|
||||
}
|
||||
}
|
||||
} while (chargedCapacitors.Length > 0 && Entity.Energy < -.01f);
|
||||
} while (chargedCapacitors > 0 && Entity.Energy < -.01f);
|
||||
}
|
||||
|
||||
// We still have an energy deficit, have to overload the reactor, run at reduced efficiency
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public class ResourceScanner : IBehavior, IAlwaysUpdatedBehavior
|
|||
{
|
||||
if(Asteroid > -1 &&
|
||||
Asteroid < beltData.Asteroids.Length &&
|
||||
length(Entity.Position.xz - Entity.Zone.GetAsteroidTransform(ScanTarget, Asteroid).xy) < Range)
|
||||
length(Entity.Position.xz - Entity.Zone.AsteroidBelts[ScanTarget].Positions[Asteroid].xz) < Range)
|
||||
{
|
||||
_scanTime += delta;
|
||||
if (_scanTime > ScanDuration)
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public class SurveyController : ControllerBase<Survey>, IBehavior, IPersistentBe
|
|||
if (planet is AsteroidBeltData)
|
||||
{
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, Entity.Position.xz);
|
||||
return Zone.GetAsteroidTransform(planet.ID, asteroid).xy;
|
||||
return Zone.AsteroidBelts[planet.ID].Positions[asteroid].xz;
|
||||
}
|
||||
return Zone.GetOrbitPosition(planet.Orbit);
|
||||
}
|
||||
|
|
@ -128,7 +128,7 @@ public class SurveyController : ControllerBase<Survey>, IBehavior, IPersistentBe
|
|||
if (planet is AsteroidBeltData)
|
||||
{
|
||||
if(asteroid == -1) asteroid = Zone.NearestAsteroid(planet.ID, Entity.Position.xz);
|
||||
return Zone.GetAsteroidVelocity(planet.ID, asteroid);
|
||||
return Zone.AsteroidBelts[planet.ID].Velocities[asteroid];
|
||||
}
|
||||
return Zone.GetOrbitVelocity(planet.Orbit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public abstract class Entity
|
|||
public float2 Velocity;
|
||||
|
||||
public float[,] Temperature;
|
||||
public float[,] NewTemperature;
|
||||
public bool2[,] HullConductivity;
|
||||
public float[,] ThermalMass;
|
||||
public float Energy;
|
||||
|
|
@ -122,6 +123,7 @@ public abstract class Entity
|
|||
Equipment.Add(new EquippedItem(ItemManager, Hull, int2.zero, this));
|
||||
Mass = hullData.Mass;
|
||||
Temperature = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
NewTemperature = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
HullConductivity = new bool2[hullData.Shape.Width,hullData.Shape.Height];
|
||||
ThermalMass = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
Armor = new float[hullData.Shape.Width, hullData.Shape.Height];
|
||||
|
|
@ -511,7 +513,7 @@ public abstract class Entity
|
|||
public virtual void Update(float delta)
|
||||
{
|
||||
var hullData = ItemManager.GetData(Hull) as HullData;
|
||||
float[,] newTemp = new float[hullData.Shape.Width,hullData.Shape.Height];
|
||||
//float[,] newTemp = new float[hullData.Shape.Width,hullData.Shape.Height];
|
||||
var radiation = 0f;
|
||||
foreach (var v in hullData.Shape.Coordinates)
|
||||
{
|
||||
|
|
@ -542,23 +544,25 @@ public abstract class Entity
|
|||
(GearOccupancy[v.x, v.y + 1]?.Conductivity ?? 1) *
|
||||
(HullConductivity[v.x, v.y].y ? hullData.Conductivity : 1 / hullData.Conductivity);
|
||||
|
||||
newTemp[v.x, v.y] = Temperature[v.x, v.y] + heatTransfer * min(ItemManager.GameplaySettings.HeatConductionMultiplier * delta,1) / ThermalMass[v.x,v.y];
|
||||
NewTemperature[v.x, v.y] = Temperature[v.x, v.y] + heatTransfer * min(ItemManager.GameplaySettings.HeatConductionMultiplier * delta,1) / ThermalMass[v.x,v.y];
|
||||
|
||||
// For all cells on the border of the entity, radiate some heat into space, increasing the visibility of the ship
|
||||
if (Parent==null && !hullData.InteriorCells[v])
|
||||
{
|
||||
var rad = pow(newTemp[v.x, v.y], ItemManager.GameplaySettings.HeatRadiationExponent) *
|
||||
var rad = pow(NewTemperature[v.x, v.y], ItemManager.GameplaySettings.HeatRadiationExponent) *
|
||||
ItemManager.GameplaySettings.HeatRadiationMultiplier;
|
||||
newTemp[v.x, v.y] -= rad * delta;
|
||||
NewTemperature[v.x, v.y] -= rad * delta;
|
||||
radiation += rad;
|
||||
}
|
||||
|
||||
if(float.IsNaN(newTemp[v.x, v.y]) || newTemp[v.x, v.y] < 0)
|
||||
if(float.IsNaN(NewTemperature[v.x, v.y]) || NewTemperature[v.x, v.y] < 0)
|
||||
ItemManager.Log("HOUSTON, WE HAVE A PROBLEM!");
|
||||
}
|
||||
|
||||
VisibilitySources[this] = radiation;
|
||||
Temperature = newTemp;
|
||||
var swap = Temperature;
|
||||
Temperature = NewTemperature;
|
||||
NewTemperature = swap;
|
||||
|
||||
if (Active)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -221,7 +221,14 @@ public class ItemManager
|
|||
{
|
||||
if (StatQuality.ContainsKey((stat, item)))
|
||||
return StatQuality[(stat, item)];
|
||||
|
||||
|
||||
var quality = CalcQuality(stat, item);
|
||||
StatQuality[(stat, item)] = quality;
|
||||
return quality;
|
||||
}
|
||||
|
||||
private float CalcQuality(PerformanceStat stat, EquippableItem item)
|
||||
{
|
||||
var itemData = GetData(item);
|
||||
var blueprint = ItemData.Get<BlueprintData>(item.Blueprint);
|
||||
var activeEffects = blueprint.StatEffects.Where(x => GetAffectedStat(blueprint, x) == stat).ToArray();
|
||||
|
|
@ -249,7 +256,6 @@ public class ItemManager
|
|||
quality = sum / ingredients.Length;
|
||||
}
|
||||
|
||||
StatQuality[(stat, item)] = quality;
|
||||
return quality;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UniRx;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
|
@ -30,6 +32,7 @@ public class Zone
|
|||
private Random _random;
|
||||
|
||||
public ZoneData Data { get; }
|
||||
private List<Task> BeltUpdates = new List<Task>();
|
||||
|
||||
public Zone(PlanetSettings settings, ZonePack pack)
|
||||
{
|
||||
|
|
@ -84,6 +87,9 @@ public class Zone
|
|||
{
|
||||
_time = time;
|
||||
_updatedOrbits.Clear();
|
||||
foreach (var t in BeltUpdates)
|
||||
t.Wait();
|
||||
BeltUpdates.Clear();
|
||||
foreach (var orbit in Orbits)
|
||||
{
|
||||
orbit.Value.PreviousPosition = orbit.Value.Position;
|
||||
|
|
@ -91,8 +97,14 @@ public class Zone
|
|||
orbit.Value.Velocity = (orbit.Value.Position - orbit.Value.PreviousPosition) / deltaTime;
|
||||
}
|
||||
|
||||
foreach (var asteroids in AsteroidBelts.Keys)
|
||||
UpdateAsteroidTransforms(asteroids);
|
||||
foreach (var belt in AsteroidBelts)
|
||||
{
|
||||
Array.Copy(belt.Value.NewPositions, belt.Value.Positions, belt.Value.Positions.Length);
|
||||
Array.Copy(belt.Value.NewVelocities, belt.Value.Velocities, belt.Value.Velocities.Length);
|
||||
Array.Copy(belt.Value.NewScales, belt.Value.Scales, belt.Value.Scales.Length);
|
||||
Array.Copy(belt.Value.NewRotations, belt.Value.Rotations, belt.Value.Rotations.Length);
|
||||
BeltUpdates.Add(Task.Run(() => UpdateAsteroidTransformsAsync(belt.Key)));
|
||||
}
|
||||
|
||||
foreach (var entity in Entities) entity.Update(deltaTime);
|
||||
}
|
||||
|
|
@ -144,13 +156,13 @@ public class Zone
|
|||
{
|
||||
var beltData = Planets[planetDataID] as AsteroidBeltData;
|
||||
|
||||
var asteroidPositions = GetAsteroidTransforms(planetDataID);
|
||||
var asteroidPositions = AsteroidBelts[planetDataID].Positions;
|
||||
|
||||
int nearest = 0;
|
||||
float nearestDistance = Single.MaxValue;
|
||||
for (int i = 0; i < beltData.Asteroids.Length; i++)
|
||||
{
|
||||
var dist = lengthsq(asteroidPositions[i].xy - position);
|
||||
var dist = lengthsq(asteroidPositions[i].xz - position);
|
||||
if (AsteroidExists(planetDataID, i) && dist < nearestDistance)
|
||||
{
|
||||
nearest = i;
|
||||
|
|
@ -163,28 +175,11 @@ public class Zone
|
|||
|
||||
public bool AsteroidExists(Guid planetDataID, int asteroid) => ((AsteroidBeltData) Planets[planetDataID]).Asteroids.Length > asteroid && asteroid >= 0;
|
||||
|
||||
public float2 GetAsteroidVelocity(Guid planetDataID, int asteroid)
|
||||
{
|
||||
return (AsteroidBelts[planetDataID].Transforms[asteroid].xy - AsteroidBelts[planetDataID].PreviousTransforms[asteroid].xy);
|
||||
}
|
||||
|
||||
public float4 GetAsteroidTransform(Guid planetDataID, int asteroid)
|
||||
{
|
||||
return AsteroidBelts[planetDataID].Transforms[asteroid];
|
||||
}
|
||||
|
||||
public float4[] GetAsteroidTransforms(Guid planetDataID)
|
||||
{
|
||||
return AsteroidBelts[planetDataID].Transforms;
|
||||
}
|
||||
|
||||
private void UpdateAsteroidTransforms(Guid planetDataID)
|
||||
private void UpdateAsteroidTransformsAsync(Guid planetDataID)
|
||||
{
|
||||
var beltData = Planets[planetDataID] as AsteroidBeltData;
|
||||
|
||||
var belt = AsteroidBelts[planetDataID];
|
||||
|
||||
Array.Copy(belt.Transforms, belt.PreviousTransforms, beltData.Asteroids.Length);
|
||||
|
||||
var orbitData = Orbits[beltData.Orbit].Data;
|
||||
var orbitPosition = GetOrbitPosition(orbitData.Parent);
|
||||
|
|
@ -199,11 +194,13 @@ public class Zone
|
|||
size = Settings.AsteroidSize.Evaluate(damage * beltData.Asteroids[i].Size);
|
||||
}
|
||||
else size = Settings.AsteroidSize.Evaluate(beltData.Asteroids[i].Size);
|
||||
|
||||
belt.Transforms[i] = float4(
|
||||
OrbitData.Evaluate((float) frac(_time / Settings.OrbitPeriod.Evaluate(beltData.Asteroids[i].Distance) +
|
||||
beltData.Asteroids[i].Phase)) * beltData.Asteroids[i].Distance + orbitPosition,
|
||||
(float) (_time * beltData.Asteroids[i].RotationSpeed % (PI * 2)), size);
|
||||
|
||||
belt.NewRotations[i] = _time * beltData.Asteroids[i].RotationSpeed % (PI * 2);
|
||||
belt.NewScales[i] = size;
|
||||
var pos = OrbitData.Evaluate(frac(_time / Settings.OrbitPeriod.Evaluate(beltData.Asteroids[i].Distance) +
|
||||
beltData.Asteroids[i].Phase)) * beltData.Asteroids[i].Distance + orbitPosition;
|
||||
belt.NewVelocities[i] = pos - belt.Positions[i].xz;
|
||||
belt.NewPositions[i] = float3(pos.x, GetHeight(pos), pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +229,7 @@ public class Zone
|
|||
{
|
||||
var beltData = Planets[asteroidBelt] as AsteroidBeltData;
|
||||
var belt = AsteroidBelts[asteroidBelt];
|
||||
var asteroidTransform = belt.Transforms[asteroid];
|
||||
//var asteroidTransform = belt.Transforms[asteroid];
|
||||
|
||||
var size = beltData.Asteroids[asteroid].Size;
|
||||
var asteroidHitpoints = Settings.AsteroidHitpoints.Evaluate(size);
|
||||
|
|
@ -272,7 +269,7 @@ public class Zone
|
|||
float result = -PowerPulse(length(position)/(Data.Radius*2), Settings.ZoneDepthExponent) * Settings.ZoneDepth;
|
||||
foreach (var body in PlanetInstances.Values)
|
||||
{
|
||||
var p = (position - body.Orbit.Position); //GetOrbitPosition(body.BodyData.Orbit)
|
||||
var p = position - body.Orbit.Position; //GetOrbitPosition(body.BodyData.Orbit)
|
||||
var distSqr = lengthsq(p);
|
||||
var gravityRadius = body.GravityWellRadius.Value;
|
||||
if (distSqr < gravityRadius*gravityRadius)
|
||||
|
|
@ -389,8 +386,14 @@ public class GasGiant : Planet
|
|||
public class AsteroidBelt
|
||||
{
|
||||
public AsteroidBeltData Data;
|
||||
public float4[] Transforms; // x, y, rotation, scale
|
||||
public float4[] PreviousTransforms; // x, y, rotation, scale
|
||||
public float3[] Positions; // x, y, rotation, scale
|
||||
public float3[] NewPositions; // x, y, rotation, scale
|
||||
public float2[] Velocities;
|
||||
public float2[] NewVelocities;
|
||||
public float[] Rotations;
|
||||
public float[] NewRotations;
|
||||
public float[] Scales;
|
||||
public float[] NewScales;
|
||||
public Dictionary<int, float> RespawnTimers = new Dictionary<int, float>();
|
||||
public Dictionary<int, float> Damage = new Dictionary<int, float>();
|
||||
public Dictionary<(Entity, int), float> MiningAccumulator = new Dictionary<(Entity, int), float>();
|
||||
|
|
@ -398,8 +401,14 @@ public class AsteroidBelt
|
|||
public AsteroidBelt(AsteroidBeltData data)
|
||||
{
|
||||
Data = data;
|
||||
Transforms = new float4[data.Asteroids.Length];
|
||||
PreviousTransforms = new float4[data.Asteroids.Length];
|
||||
Positions = new float3[data.Asteroids.Length];
|
||||
NewPositions = new float3[data.Asteroids.Length];
|
||||
Velocities = new float2[data.Asteroids.Length];
|
||||
NewVelocities = new float2[data.Asteroids.Length];
|
||||
Rotations = new float[data.Asteroids.Length];
|
||||
NewRotations = new float[data.Asteroids.Length];
|
||||
Scales = new float[data.Asteroids.Length];
|
||||
NewScales = new float[data.Asteroids.Length];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue