This PR aims to fix the Translation Gizmo (issue #50), and a handful of other transform issues generally stemming from matrix multiplication.
An additional feature has been added to store a model's original LocalMatrix transform, and allow users to reset the model's transform from the Model menu.
Lastly, a UI thread issue has been fixed with PreviewForm and LauncherForm, where these classes were constructed outside the UI thread, but run by the application inside the thread. I have no idea how this didn't cause problems sooner, since I only encountered an issue after adding a submenu under the Model menu.
Added properties Translation, Rotation, and Scale to store the entity's transform components so that translation with the Gizmo wouldn't slowly rotate the entity (if it had any rotation). Assigning to LocalMatrix will now update the 3 components, and changing any of the 3 components will update LocalMatrix.
Added OriginalLocalMatrix property (which should now be assigned instead of LocalMatrix when first setting the transform). This property exists so that the user can reset any transform applied to the model back to the default.
HMDParser and PSXParser now assign to this property instead of LocalMatrix.
WorldMatrix
Fixed matrix multiplication order (matrix * entity.LocalMatrix). This was causing issues where sub-models with rotation were being translated in their orientation's direction when trying to move the root entity with the translation Gizmo.
ResetTransform
Added function to automatically handle assigning OriginalLocalMatrix to LocalMatrix for the calling entity, and optionally all children.
ApplyTranslation → ApplyTransform
This function now multiplies the transform components in the right order (scale * rotation * translation), thus fixing the issue with Gizmo translation that would often throw the model all over the place.
This function has been renamed and changed to a more general ApplyTransform, where optional arguments are present for all three transform components. Any arguments not specified will use the stored component properties.
GetRootEntity
Changed function to start entity on this instead of ParentEntity. This way GetRootEntity can be called by the RootEntity class without returning null.
One instance where this behavior was worked around in PreviewForm.UpdateSelectedEntity has been simplified, since there's no longer any worry of GetRootEntity returning null.
PreviewForm
Under the Model menu, the following submenu structure has been added (below Export Selected). These two options allow the user to reset any translation applied to either the whole model and its children of the selected root or sub-model, or just the selected root or sub-model.
In the future when sub-sub-model support is added, the Reset Whole Model menu item could be changed to instead only reset the selected model and its children, but not the whole model, since you could just select the root to do this instead.
Export Selected ▹
Reset Transform ▹
Reset Whole Model
Reset Selected Model
----------
Wireframe
...
Program
Fixed UI thread error by making sure LauncherForm and PreviewForm are constructed in their own thread, rather than the main thread.
To ensure thread safety, both Forms have been marked as volatile, and an event wait handle has been added for each form to ensure the field is assigned before continuing execution.
Short explanation
This PR aims to fix the Translation Gizmo (issue #50), and a handful of other transform issues generally stemming from matrix multiplication.
An additional feature has been added to store a model's original
LocalMatrix
transform, and allow users to reset the model's transform from the Model menu.Lastly, a UI thread issue has been fixed with
PreviewForm
andLauncherForm
, where these classes were constructed outside the UI thread, but run by the application inside the thread. I have no idea how this didn't cause problems sooner, since I only encountered an issue after adding a submenu under the Model menu.Preview: UI thread error
![image](https://github.com/rickomax/psxprev/assets/9752430/b115170b-b38d-44d8-b0f4-e1950bcdae29)Detailed explanation
EntityBase
Translation
,Rotation
, andScale
to store the entity's transform components so that translation with the Gizmo wouldn't slowly rotate the entity (if it had any rotation). Assigning toLocalMatrix
will now update the 3 components, and changing any of the 3 components will updateLocalMatrix
.OriginalLocalMatrix
property (which should now be assigned instead ofLocalMatrix
when first setting the transform). This property exists so that the user can reset any transform applied to the model back to the default.HMDParser
andPSXParser
now assign to this property instead ofLocalMatrix
.WorldMatrix
matrix * entity.LocalMatrix
). This was causing issues where sub-models with rotation were being translated in their orientation's direction when trying to move the root entity with the translation Gizmo.ResetTransform
OriginalLocalMatrix
toLocalMatrix
for the calling entity, and optionally all children.ApplyTranslation → ApplyTransform
scale * rotation * translation
), thus fixing the issue with Gizmo translation that would often throw the model all over the place.ApplyTransform
, where optional arguments are present for all three transform components. Any arguments not specified will use the stored component properties.GetRootEntity
entity
onthis
instead ofParentEntity
. This wayGetRootEntity
can be called by theRootEntity
class without returningnull
.PreviewForm.UpdateSelectedEntity
has been simplified, since there's no longer any worry ofGetRootEntity
returningnull
.PreviewForm
Program
LauncherForm
andPreviewForm
are constructed in their own thread, rather than the main thread.