Skip to content

Commit 9a6967d

Browse files
[Physics] Fix cleanup for Jolt Physics;
[Entities] Added Component Versions and a tracker class for it and removed transform Changed flags and transform tracking;
1 parent 380337c commit 9a6967d

File tree

16 files changed

+121
-111
lines changed

16 files changed

+121
-111
lines changed

Engine/Staple.Core.Tests/Entities/TransformTests.cs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,79 +10,67 @@ public void TestChanged()
1010
{
1111
var transform = new Transform();
1212

13-
Assert.That(transform.Changed, Is.False);
13+
Assert.That(transform.Version, Is.EqualTo(0));
1414

1515
transform.LocalPosition = transform.LocalPosition;
1616

17-
Assert.That(transform.Changed, Is.False);
17+
Assert.That(transform.Version, Is.EqualTo(0));
1818

1919
transform.LocalRotation = transform.LocalRotation;
2020

21-
Assert.That(transform.Changed, Is.False);
21+
Assert.That(transform.Version, Is.EqualTo(0));
2222

2323
transform.LocalScale = transform.LocalScale;
2424

25-
Assert.That(transform.Changed, Is.False);
25+
Assert.That(transform.Version, Is.EqualTo(0));
2626

2727
transform.Position = transform.Position;
2828

29-
Assert.That(transform.Changed, Is.False);
29+
Assert.That(transform.Version, Is.EqualTo(0));
3030

3131
transform.Rotation = transform.Rotation;
3232

33-
Assert.That(transform.Changed, Is.False);
33+
Assert.That(transform.Version, Is.EqualTo(0));
3434

3535
transform.Scale = transform.Scale;
3636

37-
Assert.That(transform.Changed, Is.False);
37+
Assert.That(transform.Version, Is.EqualTo(0));
3838

3939
transform.LocalPosition = Vector3.One;
4040

41-
Assert.That(transform.Changed, Is.True);
42-
43-
transform.Changed = false;
41+
Assert.That(transform.Version, Is.EqualTo(1));
4442

4543
transform.LocalRotation = Quaternion.CreateFromYawPitchRoll(1, 2, 3);
4644

47-
Assert.That(transform.Changed, Is.True);
48-
49-
transform.Changed = false;
45+
Assert.That(transform.Version, Is.EqualTo(2));
5046

5147
transform.LocalScale = Vector3.Zero;
5248

53-
Assert.That(transform.Changed, Is.True);
54-
55-
transform.Changed = false;
49+
Assert.That(transform.Version, Is.EqualTo(3));
5650

5751
transform.Position = Vector3.Zero;
5852

59-
Assert.That(transform.Changed, Is.True);
60-
61-
transform.Changed = false;
53+
Assert.That(transform.Version, Is.EqualTo(4));
6254

6355
transform.Rotation = Quaternion.Identity;
6456

65-
Assert.That(transform.Changed, Is.True);
66-
67-
transform.Changed = false;
57+
Assert.That(transform.Version, Is.EqualTo(5));
6858

6959
transform.Scale = Vector3.One;
7060

71-
Assert.That(transform.Changed, Is.True);
72-
73-
transform.Changed = false;
61+
Assert.That(transform.Version, Is.EqualTo(6));
7462
}
7563

7664
[Test]
7765
public void TestLocalPosition()
7866
{
7967
var transform = new Transform();
8068

81-
Assert.That(transform.Changed, Is.False);
69+
Assert.That(transform.Version, Is.EqualTo(0));
8270

8371
transform.LocalPosition = new Vector3(0, 0, 1);
8472

85-
Assert.That(transform.Changed, Is.True);
73+
Assert.That(transform.Version, Is.EqualTo(1));
8674

8775
var matrix = transform.Matrix;
8876

@@ -94,11 +82,11 @@ public void TestLocalRotation()
9482
{
9583
var transform = new Transform();
9684

97-
Assert.That(transform.Changed, Is.False);
85+
Assert.That(transform.Version, Is.EqualTo(0));
9886

9987
transform.LocalRotation = Quaternion.Euler(new Vector3(0, 90, 0));
10088

101-
Assert.That(transform.Changed, Is.True);
89+
Assert.That(transform.Version, Is.EqualTo(1));
10290

10391
var matrix = transform.Matrix;
10492

@@ -118,11 +106,11 @@ public void TestLocalScale()
118106
{
119107
var transform = new Transform();
120108

121-
Assert.That(transform.Changed, Is.False);
109+
Assert.That(transform.Version, Is.EqualTo(0));
122110

123111
transform.LocalScale = Vector3.One * 0.5f;
124112

125-
Assert.That(transform.Changed, Is.True);
113+
Assert.That(transform.Version, Is.EqualTo(1));
126114

127115
var matrix = transform.Matrix;
128116

@@ -143,7 +131,7 @@ public void TestPosition()
143131

144132
transform.LocalPosition = new Vector3(0, 0, 1);
145133

146-
Assert.That(transform.Changed, Is.True);
134+
Assert.That(transform.Version, Is.EqualTo(2));
147135

148136
Assert.That(transform.Position, Is.EqualTo(new Vector3(0, 0, 1)));
149137

@@ -166,7 +154,7 @@ public void TestRotation()
166154

167155
transform.LocalRotation = Quaternion.Euler(new(0, 45, 0));
168156

169-
Assert.That(transform.Changed, Is.True);
157+
Assert.That(transform.Version, Is.EqualTo(2));
170158

171159
var angles = transform.Rotation.ToEulerAngles();
172160

@@ -207,7 +195,7 @@ public void TestScale()
207195

208196
transform.LocalScale = new Vector3(2, 2, 2);
209197

210-
Assert.That(transform.Changed, Is.True);
198+
Assert.That(transform.Version, Is.EqualTo(2));
211199

212200
Assert.That(transform.Scale, Is.EqualTo(new Vector3(2, 2, 2)));
213201

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Staple;
5+
6+
public class ComponentVersionTracker
7+
{
8+
private readonly Dictionary<int, ulong> versions = [];
9+
10+
public void Clear()
11+
{
12+
versions.Clear();
13+
}
14+
15+
public bool ShouldUpdateComponent<T>(Entity entity, in T component) where T : IComponent, IComponentVersion
16+
{
17+
if (component == null)
18+
{
19+
throw new ArgumentNullException(nameof(component), "Component can't be null");
20+
}
21+
22+
var hashCode = HashCode.Combine(entity, component.GetType().FullName.GetHashCode());
23+
24+
if (versions.TryGetValue(hashCode, out var version) == false)
25+
{
26+
versions.Add(hashCode, component.Version);
27+
28+
return true;
29+
}
30+
31+
return version != component.Version;
32+
}
33+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Staple;
2+
3+
public interface IComponentVersion
4+
{
5+
ulong Version { get; }
6+
}

Engine/Staple.Core/Entities/Transform.cs

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,35 @@ namespace Staple;
99
/// Contains rotation, position, scale, and parent entity.
1010
/// </summary>
1111
[AutoAssignEntity]
12-
public class Transform : IComponent
12+
public class Transform : IComponent, IComponentVersion
1313
{
14-
internal bool changed = false;
15-
internal bool changedThisFrame = false;
14+
private ulong lastVersion = 0;
15+
internal ulong version;
1616

1717
/// <summary>
1818
/// Whether the transform has changed.
1919
/// This is used to force children to refresh themselves when the parent is modified.
2020
/// </summary>
21-
internal bool Changed
21+
public ulong Version
2222
{
23-
get => changed;
23+
get => version;
2424

25-
set
25+
private set
2626
{
27-
var wasChanged = changed;
27+
var previous = version;
2828

29-
changed = value;
29+
version = value;
3030

31-
if(changed)
32-
{
33-
changedThisFrame = true;
34-
}
35-
36-
if(wasChanged == false && changed)
31+
if(previous != version)
3732
{
3833
for(var i = 0; i < Children.Length; i++)
3934
{
40-
Children[i].Changed = true;
35+
Children[i].Version++;
4136
}
4237
}
4338
}
4439
}
4540

46-
/// <summary>
47-
/// Whether the transform was changed this frame
48-
/// </summary>
49-
public bool ChangedThisFrame => changedThisFrame;
50-
5141
/// <summary>
5242
/// Child transforms
5343
/// </summary>
@@ -134,7 +124,10 @@ public Vector3 Position
134124

135125
var target = value - parentPosition;
136126

137-
Changed |= target != position;
127+
if(target != position)
128+
{
129+
Version++;
130+
}
138131

139132
position = target;
140133
}
@@ -149,7 +142,10 @@ public Vector3 LocalPosition
149142

150143
set
151144
{
152-
Changed |= value != position;
145+
if(value != position)
146+
{
147+
Version++;
148+
}
153149

154150
position = value;
155151
}
@@ -173,7 +169,10 @@ public Vector3 Scale
173169

174170
var target = value / parentScale;
175171

176-
Changed |= target != scale;
172+
if (target != scale)
173+
{
174+
Version++;
175+
}
177176

178177
scale = target;
179178
}
@@ -188,7 +187,10 @@ public Vector3 LocalScale
188187

189188
set
190189
{
191-
Changed |= value != scale;
190+
if (value != scale)
191+
{
192+
Version++;
193+
}
192194

193195
scale = value;
194196
}
@@ -212,7 +214,10 @@ public Quaternion Rotation
212214

213215
var target = Quaternion.Inverse(parentRotation) * value;
214216

215-
Changed |= target != rotation;
217+
if (target != rotation)
218+
{
219+
Version++;
220+
}
216221

217222
rotation = target;
218223
}
@@ -227,7 +232,10 @@ public Quaternion LocalRotation
227232

228233
set
229234
{
230-
Changed |= value != rotation;
235+
if (value != rotation)
236+
{
237+
Version++;
238+
}
231239

232240
rotation = value;
233241
}
@@ -345,7 +353,7 @@ public void SetParent(Transform parent)
345353

346354
parent?.AttachChild(this);
347355

348-
Changed = true;
356+
Version++;
349357

350358
Scene.RequestWorldUpdate();
351359
}
@@ -356,9 +364,9 @@ public void SetParent(Transform parent)
356364
[MethodImpl(MethodImplOptions.AggressiveInlining)]
357365
private void UpdateState()
358366
{
359-
if (changed)
367+
if (version > lastVersion)
360368
{
361-
changed = false;
369+
lastVersion = version;
362370

363371
matrix = Matrix4x4.TRS(position, scale, rotation);
364372

Engine/Staple.Core/Rendering/Animation/SkinnedMeshRenderSystem.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Numerics;
45

@@ -29,6 +30,8 @@ private struct RenderInfo
2930

3031
private readonly SceneQuery<SkinnedMeshInstance, Transform> instances = new();
3132

33+
private readonly ComponentVersionTracker transformVersions = new();
34+
3235
public bool UsesOwnRenderProcess => false;
3336

3437
public Type RelatedComponent => typeof(SkinnedMeshRenderer);
@@ -66,7 +69,7 @@ public void Preprocess(Span<RenderEntry> renderQueue, Camera activeCamera, Trans
6669
continue;
6770
}
6871

69-
if (entry.transform.ChangedThisFrame || renderer.localBounds.size == Vector3.Zero)
72+
if (transformVersions.ShouldUpdateComponent(entry.entity, in entry.transform))
7073
{
7174
var localSize = Vector3.Abs(renderer.mesh.bounds.size.Transformed(entry.transform.LocalRotation));
7275

Engine/Staple.Core/Rendering/Mesh/MeshCombineSystem.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ private struct RenderInfo
3131

3232
private readonly ExpandableContainer<RenderInfo> renderers = new();
3333

34+
private readonly ComponentVersionTracker transformVersions = new();
35+
3436
#region Lifecycle
3537
public void Prepare()
3638
{
@@ -257,7 +259,7 @@ void ApplyIfValid<T>(ref T[] target, List<T> source)
257259
}
258260
}
259261

260-
if (entry.transform.ChangedThisFrame || combine.localBounds.size == Vector3.Zero)
262+
if (transformVersions.ShouldUpdateComponent(entry.entity, in entry.transform))
261263
{
262264
var localSize = Vector3.Abs(combine.combinedMeshBounds.size.Transformed(entry.transform.LocalRotation));
263265

Engine/Staple.Core/Rendering/Mesh/MeshRenderSystem.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private class InstanceData
4343
.Build();
4444
});
4545

46+
private readonly ComponentVersionTracker transformVersions = new();
47+
4648
public bool UsesOwnRenderProcess => false;
4749

4850
public Type RelatedComponent => typeof(MeshRenderer);
@@ -145,7 +147,7 @@ public void Preprocess(Span<RenderEntry> renderQueue, Camera activeCamera, Trans
145147

146148
renderer.mesh.UploadMeshData();
147149

148-
if (entry.transform.ChangedThisFrame || renderer.localBounds.size == Vector3.Zero)
150+
if (transformVersions.ShouldUpdateComponent(entry.entity, in entry.transform))
149151
{
150152
var localSize = Vector3.Abs(renderer.mesh.bounds.size.Transformed(entry.transform.LocalRotation));
151153

0 commit comments

Comments
 (0)