|
3 | 3 | using FFXIVClientStructs.Havok.Common.Base.Math.QsTransform;
|
4 | 4 | using FFXIVClientStructs.Havok.Common.Base.Math.Quaternion;
|
5 | 5 | using FFXIVClientStructs.Havok.Common.Base.Math.Vector;
|
| 6 | +using Microsoft.Extensions.Logging; |
6 | 7 | using SharpGLTF.Transforms;
|
7 | 8 | using CSTransform = FFXIVClientStructs.FFXIV.Client.Graphics.Transform;
|
8 | 9 |
|
@@ -58,7 +59,69 @@ public Transform(Matrix4x4 transform) : this(new AffineTransform(transform)) { }
|
58 | 59 | public Vector3 Scale { get; init; }
|
59 | 60 |
|
60 | 61 | [JsonIgnore]
|
61 |
| - public AffineTransform AffineTransform => new(Scale, Rotation, Translation); |
| 62 | + public AffineTransform AffineTransform => GetAffine(); |
| 63 | + |
| 64 | + private bool IsFinite(Vector3 value) |
| 65 | + { |
| 66 | + return IsFinite(value.X) && IsFinite(value.Y) && IsFinite(value.Z); |
| 67 | + } |
| 68 | + |
| 69 | + private bool IsFinite(Quaternion value) |
| 70 | + { |
| 71 | + return IsFinite(value.X) && IsFinite(value.Y) && IsFinite(value.Z) && IsFinite(value.W); |
| 72 | + } |
| 73 | + |
| 74 | + private bool IsFinite(float value) |
| 75 | + { |
| 76 | + return !(float.IsNaN(value) || float.IsInfinity(value)); |
| 77 | + } |
| 78 | + |
| 79 | + private AffineTransform GetAffine() |
| 80 | + { |
| 81 | + try |
| 82 | + { |
| 83 | + Vector3 scale; |
| 84 | + if (!IsFinite(Scale)) |
| 85 | + { |
| 86 | + Plugin.Logger?.LogWarning("Transform contains non-finite scale, using default: {Scale} -> {DefaultValue}", Scale, Vector3.One); |
| 87 | + scale = Vector3.One; |
| 88 | + } |
| 89 | + else |
| 90 | + { |
| 91 | + scale = Scale; |
| 92 | + } |
| 93 | + |
| 94 | + Vector3 translation; |
| 95 | + if (!IsFinite(Translation)) |
| 96 | + { |
| 97 | + Plugin.Logger?.LogWarning("Transform contains non-finite translation, using default: {Translation} -> {DefaultValue}", Translation, Vector3.Zero); |
| 98 | + translation = Vector3.Zero; |
| 99 | + } |
| 100 | + else |
| 101 | + { |
| 102 | + translation = Translation; |
| 103 | + } |
| 104 | + |
| 105 | + Quaternion rotation; |
| 106 | + if (!IsFinite(Rotation)) |
| 107 | + { |
| 108 | + Plugin.Logger?.LogWarning("Transform contains non-finite rotation, using default: {Rotation} -> {DefaultValue}", Rotation, Quaternion.Identity); |
| 109 | + rotation = Quaternion.Identity; |
| 110 | + } |
| 111 | + else |
| 112 | + { |
| 113 | + rotation = Rotation; |
| 114 | + } |
| 115 | + |
| 116 | + return new AffineTransform(scale, rotation, translation); |
| 117 | + } |
| 118 | + catch (Exception ex) |
| 119 | + { |
| 120 | + Plugin.Logger?.LogError(ex, "Failed to create AffineTransform from Transform, pos: {Position}, rot: {Rotation}, scale: {Scale}", |
| 121 | + Translation, Rotation, Scale); |
| 122 | + throw new InvalidOperationException("Failed to create AffineTransform from Transform", ex); |
| 123 | + } |
| 124 | + } |
62 | 125 |
|
63 | 126 | public override string ToString()
|
64 | 127 | {
|
|
0 commit comments