From 4221602e123600140cf11327c9a5b1972041ee2b Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Wed, 11 Mar 2020 15:20:03 -0700 Subject: [PATCH] Minor tweaks to wireframe viewer Experimented with different orders of rotation for wireframe viewer. Made perspective projection the default behavior. Removed animation parameters from the stored Visualization when it's not animated. --- PluginCommon/Matrix44.cs | 66 ++++++++++++++-------- SourceGen/RuntimeData/Apple/VisHiRes.cs | 3 + SourceGen/Visualization.cs | 4 +- SourceGen/VisualizationSet.cs | 5 +- SourceGen/WpfGui/EditVisualization.xaml.cs | 25 ++++---- 5 files changed, 67 insertions(+), 36 deletions(-) diff --git a/PluginCommon/Matrix44.cs b/PluginCommon/Matrix44.cs index 9b83f43..9e52184 100644 --- a/PluginCommon/Matrix44.cs +++ b/PluginCommon/Matrix44.cs @@ -45,6 +45,8 @@ namespace PluginCommon { Val[0, 0] = Val[1, 1] = Val[2, 2] = Val[3, 3] = 1.0; } + private enum RotMode { XYZ, ZYX, ZXY }; + /// /// Sets the matrix to perform rotation about Euler angles in the order X, Y, Z. /// @@ -66,33 +68,51 @@ namespace PluginCommon { double sycx = sy * cx; double sysx = sy * sx; - bool useXyz = true; - if (useXyz) { - // R = Rz * Ry * Rx (from wikipedia) - Val[0, 0] = cz * cy; - Val[0, 1] = sz * cy; - Val[0, 2] = -sy; + RotMode rm = RotMode.ZYX; + switch (rm) { + case RotMode.ZYX: + // R = Rz * Ry * Rx (from wikipedia) + Val[0, 0] = cz * cy; + Val[0, 1] = sz * cy; + Val[0, 2] = -sy; - Val[1, 0] = cz * sysx - sz * cx; - Val[1, 1] = sz * sysx + cz * cx; - Val[1, 2] = cy * sx; + Val[1, 0] = cz * sysx - sz * cx; + Val[1, 1] = sz * sysx + cz * cx; + Val[1, 2] = cy * sx; - Val[2, 0] = cz * sycx + sz * sx; - Val[2, 1] = sz * sycx - cz * sx; - Val[2, 2] = cy * cx; - } else { - // R = Rx * Ry * Rz (from Arc3D) - Val[0, 0] = cz * cy; - Val[0, 1] = -sz * cy; - Val[0, 2] = sy; + Val[2, 0] = cz * sycx + sz * sx; + Val[2, 1] = sz * sycx - cz * sx; + Val[2, 2] = cy * cx; + break; + case RotMode.XYZ: + // R = Rx * Ry * Rz (from Arc3D) + Val[0, 0] = cz * cy; + Val[0, 1] = -sz * cy; + Val[0, 2] = sy; - Val[1, 0] = cz * sysx + sz * cx; - Val[1, 1] = -sz * sysx + cz * cx; - Val[1, 2] = -cy * sx; + Val[1, 0] = cz * sysx + sz * cx; + Val[1, 1] = -sz * sysx + cz * cx; + Val[1, 2] = -cy * sx; - Val[2, 0] = -cz * sycx + sz * sx; - Val[2, 1] = sz * sycx + cz * sx; - Val[2, 2] = cy * cx; + Val[2, 0] = -cz * sycx + sz * sx; + Val[2, 1] = sz * sycx + cz * sx; + Val[2, 2] = cy * cx; + break; + case RotMode.ZXY: + // R = Rz * Rx * Ry (from Arc3D) + double cysx = cy * sx; + Val[0, 0] = cz * cy + sz * sysx; + Val[0, 1] = -sz * cy + cz * sysx; + Val[0, 2] = sy * cx; + + Val[1, 0] = sz * cx; + Val[1, 1] = cz * cx; + Val[1, 2] = -sx; + + Val[2, 0] = -cz * sy + sz * cysx; + Val[2, 1] = sz * sy + cz * cysx; + Val[2, 2] = cy * cx; + break; } //Val[0, 3] = Val[1, 3] = Val[2, 3] = Val[3, 0] = Val[3, 1] = Val[3, 2] = 0.0; Val[3, 3] = 1.0; diff --git a/SourceGen/RuntimeData/Apple/VisHiRes.cs b/SourceGen/RuntimeData/Apple/VisHiRes.cs index fd46f1c..92dee11 100644 --- a/SourceGen/RuntimeData/Apple/VisHiRes.cs +++ b/SourceGen/RuntimeData/Apple/VisHiRes.cs @@ -19,6 +19,9 @@ using System.Collections.ObjectModel; using PluginCommon; namespace RuntimeData.Apple { + /// + /// Visualizer for Apple II hi-res bitmaps. + /// public class VisHiRes : MarshalByRefObject, IPlugin, IPlugin_Visualizer { // IPlugin public string Identifier { diff --git a/SourceGen/Visualization.cs b/SourceGen/Visualization.cs index 79696c5..55c636f 100644 --- a/SourceGen/Visualization.cs +++ b/SourceGen/Visualization.cs @@ -263,7 +263,7 @@ namespace SourceGen { int eulerX = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_X, 0); int eulerY = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Y, 0); int eulerZ = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Z, 0); - bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, false); + bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, true); bool doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false); return GenerateWireframeImage(wireObj, dim, eulerX, eulerY, eulerZ, doPersp, doBfc); } @@ -325,7 +325,7 @@ namespace SourceGen { int eulerX = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_X, 0); int eulerY = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Y, 0); int eulerZ = Util.GetFromObjDict(parms, VisWireframeAnimation.P_EULER_ROT_Z, 0); - bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, false); + bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, true); bool doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false); return GenerateWireframePath(wireObj, dim, eulerX, eulerY, eulerZ, doPersp, doBfc); } diff --git a/SourceGen/VisualizationSet.cs b/SourceGen/VisualizationSet.cs index c9d90ca..d7ad6fe 100644 --- a/SourceGen/VisualizationSet.cs +++ b/SourceGen/VisualizationSet.cs @@ -139,6 +139,8 @@ namespace SourceGen { #region Image generation private class ScriptSupport : MarshalByRefObject, PluginCommon.IApplication { + public string MsgTag { get; set; } = string.Empty; + public ScriptSupport() { } public void ReportError(string msg) { @@ -146,7 +148,7 @@ namespace SourceGen { } public void DebugLog(string msg) { - Debug.WriteLine("Vis plugin: " + msg); + Debug.WriteLine("Vis [" + MsgTag + "]: " + msg); } public bool SetOperandFormat(int offset, DataSubType subType, string label) { @@ -195,6 +197,7 @@ namespace SourceGen { iapp = new ScriptSupport(); project.PrepareScripts(iapp); } + iapp.MsgTag = vis.Tag; if (plugins == null) { plugins = project.GetActivePlugins(); diff --git a/SourceGen/WpfGui/EditVisualization.xaml.cs b/SourceGen/WpfGui/EditVisualization.xaml.cs index d0548b0..758f920 100644 --- a/SourceGen/WpfGui/EditVisualization.xaml.cs +++ b/SourceGen/WpfGui/EditVisualization.xaml.cs @@ -440,19 +440,24 @@ namespace SourceGen.WpfGui { // Strictly speaking we don't need this, because we use a different object // type, but this ties into how the object is stored in the project file. + // We add it here rather than in the project file save code so that the + // parameter manipulation is all in one place. valueDict.Add(VisWireframeAnimation.P_IS_ANIMATED, IsWireframeAnimated); - // These could be any integer value, but the UI limits them to 4 chars, and - // it's all mod 360. - valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_X, RotDeltaX); - valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_Y, RotDeltaY); - valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_Z, RotDeltaZ); + if (IsWireframeAnimated) { + // These could be any integer value, but the UI limits them to 4 chars, and + // it's all mod 360. + valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_X, RotDeltaX); + valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_Y, RotDeltaY); + valueDict.Add(VisWireframeAnimation.P_DELTA_ROT_Z, RotDeltaZ); - // These aren't strictly checked by the UI, so range-check here. - int fc = (FrameCount >= 1 && FrameCount <= 9999) ? FrameCount : 1; - valueDict.Add(VisWireframeAnimation.P_FRAME_COUNT, fc); - int dly = (FrameDelayMsec >= 1 && FrameDelayMsec <= 999999) ? FrameDelayMsec : 100; - valueDict.Add(VisWireframeAnimation.P_FRAME_DELAY_MSEC, dly); + // These aren't strictly checked by the UI, so range-check here. + int fc = (FrameCount >= 1 && FrameCount <= 9999) ? FrameCount : 1; + valueDict.Add(VisWireframeAnimation.P_FRAME_COUNT, fc); + int dly = (FrameDelayMsec >= 1 && FrameDelayMsec <= 999999) ? + FrameDelayMsec : 100; + valueDict.Add(VisWireframeAnimation.P_FRAME_DELAY_MSEC, dly); + } } return new ReadOnlyDictionary(valueDict);