Skip to content

Commit 8961347

Browse files
committed
small qol
1 parent 15112de commit 8961347

11 files changed

Lines changed: 78 additions & 35 deletions

File tree

Editor/Widgets/ViewportWidget.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ private void DrawComponentControlsOverlay(CameraComponent camera, ActorComponent
254254

255255
private void DrawOrbitCircle(InteractiveCameraComponent camera, ActorComponent? component, Vector2 contentPos, Vector2 contentSize)
256256
{
257-
var orbitCenter = camera.LocalTransform.Position - camera.Forward * camera.OrbitDistance;
257+
var orbitCenter = camera.GetLocalTransform().Position - camera.Forward * camera.OrbitDistance;
258258
var circleY = component is SpatialComponent spatial ? spatial.GizmoMatrix.Translation.Y : 0f;
259259
var viewProj = camera.ViewMatrix * camera.ProjectionMatrix;
260260

Snooper/Core/Managers/SceneManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public override void Update(float delta)
8282

8383
if (RootActor != null && MainViewport?.Camera is { } camera && camera.IsDirty(DirtyFlags.Transform))
8484
{
85-
UpdatePartitionActorsRecursive(RootActor, camera.LocalTransform.Position);
85+
UpdatePartitionActorsRecursive(RootActor, camera.GetLocalTransform().Position);
8686
}
8787

8888
base.Update(delta);

Snooper/Rendering/Actors/Actor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,12 @@ public bool IsDescendantOf(Actor other)
151151
return false;
152152
}
153153

154-
public bool AttachTo(Actor newParent, SpatialComponent? attachTo = null, string? socket = null, bool keepWorldTransform = true)
154+
public bool AttachTo(Actor newParent, SpatialComponent? attachTo = null, string? socket = null)
155155
{
156156
if (!CanAttachTo(newParent, attachTo, out var relation)) return false;
157157

158158
if (_parent != newParent) MoveUnder(newParent);
159-
RootComponent?.AttachTo(relation, socket, keepWorldTransform);
159+
RootComponent?.AttachTo(relation, socket);
160160

161161
Log.Verbose("{Actor} attached to {Target}", Name, relation?.Name ?? newParent.Name);
162162
return true;
@@ -212,15 +212,15 @@ private void MoveUnder(Actor newParent)
212212
manager.IncrementRevision();
213213
}
214214

215-
public bool Detach(bool keepWorldTransform = true)
215+
public bool Detach()
216216
{
217217
if (ActorManager is not SceneManager { RootActor: { } root })
218218
{
219219
Log.Warning("{Actor} has no scene root to be detached to", Name);
220220
return false;
221221
}
222222

223-
return root != this && AttachTo(root, root.RootComponent, null, keepWorldTransform);
223+
return root != this && AttachTo(root, root.RootComponent);
224224
}
225225

226226
internal void OnChildAdded(Actor actor)

Snooper/Rendering/Actors/CameraActor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace Snooper.Rendering.Actors;
44

55
public class CameraActor : Actor
66
{
7-
public CameraComponent CameraComponent { get; }
7+
public SceneCameraComponent CameraComponent { get; }
88

99
public CameraActor(string name) : base(name)
1010
{

Snooper/Rendering/Actors/CellActor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private void AddWorld(FSoftObjectPath world)
100100
var w = new WorldActor(world.Load<UWorld>());
101101
if (w.RootComponent != null && RootComponent != null)
102102
{
103-
w.RootComponent.SetLocalTransform(RootComponent.LocalTransform.Inverse());
103+
w.RootComponent.SetLocalTransform(RootComponent.GetLocalTransform().Inverse());
104104
}
105105

106106
Children.Add(w);

Snooper/Rendering/Actors/HierarchicalActor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public void SetVisibilityByDistance(Vector3 position, float minDistance = 0f)
5858
{
5959
foreach (var cell in Children.OfType<CellActor>().Where(x => x is { IsNonSpatiallyLoaded: false, DataLayers.Length: 0 }))
6060
{
61-
var distance = Vector3.Distance(position, cell.RootComponent?.LocalTransform.Position ?? Vector3.Zero);
61+
var distance = Vector3.Distance(position, cell.RootComponent?.GetLocalTransform().Position ?? Vector3.Zero);
6262
cell.IsVisible = distance > minDistance && distance <= LoadingRange;
6363
}
6464
}

Snooper/Rendering/Components/Primitive/PrimitiveComponent.cs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,19 +163,56 @@ protected virtual void CopyCachedData(TInstanceData[] data, TInstanceData[] cach
163163

164164
}
165165

166-
protected override (Vector3, float) GetTeleportPosition(CameraComponent camera)
166+
protected override (Vector3, float) GetTeleportPosition(CameraComponent camera, Quaternion rotation)
167167
{
168-
var vHalfFov = camera.FieldOfViewRadians / 2f;
169-
var hHalfFov = MathF.Atan(MathF.Tan(vHalfFov) * camera.AspectRatio);
170-
var limitingHalfFov = MathF.Min(vHalfFov, hHalfFov);
168+
var upLimit = MathF.Tan(camera.FieldOfViewRadians / 2f);
169+
var sideLimit = upLimit * camera.AspectRatio;
170+
171+
var forward = Vector3.Transform(Settings.ForwardVector, rotation);
172+
var right = Vector3.Transform(Settings.RightVector, rotation);
173+
var up = Vector3.Transform(Settings.UpVector, rotation);
171174

172-
var sphereRadius = Descriptor.Bounds.Extents.Length();
173-
var distance = sphereRadius / MathF.Tan(limitingHalfFov) * 1.25f;
174175
var center = Vector3.Transform(Descriptor.Bounds.Center, GizmoMatrix);
175176

177+
var distance = 0f;
178+
for (var i = 0; i < 8; i++)
179+
{
180+
var offset = Vector3.Transform(GetBoundsCorner(i), GizmoMatrix) - center;
181+
var depth = Vector3.Dot(offset, -forward);
182+
183+
distance = MathF.Max(distance, MathF.Abs(Vector3.Dot(offset, right)) / sideLimit - depth);
184+
distance = MathF.Max(distance, MathF.Abs(Vector3.Dot(offset, up)) / upLimit - depth);
185+
}
186+
176187
return (center, MathF.Max(distance, 0.1f));
177188
}
178189

190+
private Vector3 GetBoundsCorner(int index)
191+
{
192+
var extents = Descriptor.Bounds.Extents;
193+
194+
return Descriptor.Bounds.Center + new Vector3(
195+
(index & 1) == 0 ? -extents.X : extents.X,
196+
(index & 2) == 0 ? -extents.Y : extents.Y,
197+
(index & 4) == 0 ? -extents.Z : extents.Z);
198+
}
199+
200+
public void SnapToGround()
201+
{
202+
var lowest = float.MaxValue;
203+
for (var i = 0; i < 8; i++)
204+
{
205+
lowest = MathF.Min(lowest, Vector3.Transform(GetBoundsCorner(i), WorldMatrix).Y);
206+
}
207+
208+
if (lowest == 0f || !Matrix4x4.Invert(GetRelationMatrix(), out var invRelation))
209+
return;
210+
211+
var transform = GetLocalTransform();
212+
transform.Position -= Vector3.TransformNormal(new Vector3(0f, lowest, 0f), invRelation);
213+
SetLocalTransform(transform);
214+
}
215+
179216
protected override void BeginPlay(ActorManager scene)
180217
{
181218
base.BeginPlay(scene);
@@ -288,13 +325,13 @@ public override void DrawControls()
288325

289326
ImGui.BeginGroup();
290327
ImGui.SetNextItemWidth(-1);
291-
if (ImGui.BeginCombo("##SectionCombo", $"{_sectionIndex}: {GetMaterialName(selected.MaterialIndex)}"))
328+
if (ImGui.BeginCombo("##SectionCombo", $"{_sectionIndex}: {selected.Name}"))
292329
{
293330
for (var i = 0; i < lod.Sections.Length; i++)
294331
{
295332
var isSelected = i == _sectionIndex;
296333

297-
if (ImGui.Selectable($"{i}: {GetMaterialName(lod.Sections[i].MaterialIndex)}##Section{i}", isSelected))
334+
if (ImGui.Selectable($"{i}: {lod.Sections[i].Name}##Section{i}", isSelected))
298335
{
299336
_sectionIndex = i;
300337
_materialLayerIndex = 0;
@@ -331,11 +368,6 @@ public override void DrawControls()
331368
});
332369
}
333370

334-
private string GetMaterialName(uint materialIndex) =>
335-
materialIndex < Materials.Length && Materials[materialIndex] is { } section
336-
? section.MaterialDataContainer?.Name ?? Settings.NoName
337-
: Settings.NoName;
338-
339371
private void DrawInfoPopup()
340372
{
341373
var viewport = ImGui.GetMainViewport();

Snooper/Rendering/Components/Transforms/Transform.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public class Transform() : ICloneable
1111
public Quaternion Rotation = Quaternion.Identity;
1212
public Vector3 Scale = Vector3.One;
1313

14+
private const float Deg2Rad = MathF.PI / 180.0f;
15+
1416
private Transform(Transform other) : this()
1517
{
1618
Position = other.Position;
@@ -34,6 +36,11 @@ public Transform(Quaternion rotation) : this(Vector3.Zero, rotation)
3436

3537
}
3638

39+
public Transform(Vector3 position, Vector3 rotation) : this(position, Quaternion.CreateFromYawPitchRoll(rotation.X * Deg2Rad, rotation.Y * Deg2Rad, rotation.Z * Deg2Rad))
40+
{
41+
42+
}
43+
3744
public Transform(FVector position, FQuat rotation, FVector scale) : this()
3845
{
3946
Position = new Vector3(position.X, position.Z, position.Y) * Settings.GlobalScale;

Snooper/Rendering/Components/Transforms/TransformComponent.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public string? AttachSocketName
9595
}
9696
}
9797

98-
public Transform LocalTransform
98+
protected Transform LocalTransform
9999
{
100100
get;
101101
private set
@@ -167,7 +167,7 @@ public Matrix4x4 GetRelationMatrix()
167167
return relationMatrix;
168168
}
169169

170-
public bool AttachTo(SpatialComponent? newRelation, string? socket = null, bool keepWorldTransform = true)
170+
public bool AttachTo(SpatialComponent? newRelation, string? socket = null)
171171
{
172172
if (newRelation == Relation && socket == AttachSocketName) return true;
173173

@@ -177,7 +177,8 @@ public bool AttachTo(SpatialComponent? newRelation, string? socket = null, bool
177177
if (Relation != newRelation) return false;
178178

179179
AttachSocketName = socket;
180-
if (keepWorldTransform) KeepWorldTransform(worldBefore);
180+
if (socket == null) KeepWorldTransform(worldBefore);
181+
else SetLocalTransform(Transform.Identity);
181182

182183
return true;
183184
}
@@ -276,14 +277,17 @@ protected virtual void ResetLocalTransform(int index = -1)
276277

277278
public virtual Matrix4x4[] GetWorldMatrices(int index = -1) => [WorldMatrix];
278279

279-
protected virtual (Vector3, float) GetTeleportPosition(CameraComponent camera) => (GizmoMatrix.Translation, 2.50f);
280+
protected virtual (Vector3, float) GetTeleportPosition(CameraComponent camera, Quaternion rotation) => (GizmoMatrix.Translation, 2.50f);
280281

281282
public void TeleportTo()
282283
{
283-
if (Actor?.ActorManager is not SceneManager { MainViewport.Camera: { } camera })
284+
if (Actor?.ActorManager is not SceneManager manager)
284285
return;
285286

286-
var (center, distance) = GetTeleportPosition(camera);
287+
var camera = manager.MainViewport?.Camera ?? manager.RootActor?.Children.OfType<CameraActor>().FirstOrDefault()?.CameraComponent;
288+
if (camera is null) return;
289+
290+
var (center, distance) = GetTeleportPosition(camera, camera.LocalTransform.Rotation);
287291
camera.TeleportTo(center, distance);
288292
}
289293

@@ -590,8 +594,7 @@ private void DrawSocketEntry(SocketEntry entry)
590594
var selected = entry.Value == AttachSocketName;
591595
if (ImGui.Selectable(entry.Label, selected))
592596
{
593-
// keep the local transform: picking a socket means "put it there", not "hold it where it is"
594-
AttachTo(Relation, entry.Value, keepWorldTransform: false);
597+
AttachTo(Relation, entry.Value);
595598
}
596599
if (selected) ImGui.SetItemDefaultFocus();
597600
}

Snooper/Rendering/Systems/AudioSystem.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ protected override void OnComponentUpdate(AudioComponent component, float delta)
8686
if (component.IsDirty(DirtyFlags.Transform))
8787
{
8888
source.SetPosition(component.WorldMatrix.Translation);
89-
source.SetDirection(Vector3.Transform(Vector3.UnitZ, component.LocalTransform.Rotation));
89+
source.SetDirection(Vector3.Transform(Vector3.UnitZ, component.GetLocalTransform().Rotation));
9090
}
9191

9292
if (component.ShouldPlay && !source.IsPlaying)
@@ -104,8 +104,9 @@ protected override void OnExecute(CameraComponent camera)
104104
if (_context == ALContext.Null) return;
105105

106106
var position = camera.WorldMatrix.Translation;
107-
var forward = Vector3.Transform(Vector3.UnitZ, camera.LocalTransform.Rotation);
108-
var up = Vector3.Transform(Vector3.UnitY, camera.LocalTransform.Rotation);
107+
var rotation = camera.GetLocalTransform().Rotation;
108+
var forward = Vector3.Transform(Vector3.UnitZ, rotation);
109+
var up = Vector3.Transform(Vector3.UnitY, rotation);
109110

110111
ALC.MakeContextCurrent(_context);
111112
AL.Listener(ALListener3f.Position, position.X, position.Y, position.Z);
@@ -140,7 +141,7 @@ protected override void OnActorComponentRemoved(AudioComponent component, EEndPl
140141

141142
var source = new AudioSource(buffer);
142143
source.SetPosition(component.WorldMatrix.Translation);
143-
source.SetDirection(Vector3.Transform(Vector3.UnitZ, component.LocalTransform.Rotation));
144+
source.SetDirection(Vector3.Transform(Vector3.UnitZ, component.GetLocalTransform().Rotation));
144145
source.SetLooping(true);
145146
source.SetGain(component.VolumeMultiplier * LinearToLogarithmicVolume(_volume));
146147
source.SetReferenceDistance(component.AttenuationDistance);

0 commit comments

Comments
 (0)