diff --git a/SourceGen/Exporter.cs b/SourceGen/Exporter.cs
index 657fe9a..a3eeaf3 100644
--- a/SourceGen/Exporter.cs
+++ b/SourceGen/Exporter.cs
@@ -808,7 +808,6 @@ namespace SourceGen {
Debug.Assert(false); // not expected
}
}
-
#if false
// try feeding the animated GIF into our GIF unpacker
using (MemoryStream ms = new MemoryStream()) {
@@ -828,8 +827,25 @@ namespace SourceGen {
}
} catch (Exception ex) {
// TODO: add an error report
- Debug.WriteLine("Error creating animated GIF file '" + pathName + "': " +
- ex.Message);
+ Debug.WriteLine("Error creating animated GIF file '" + pathName +
+ "': " + ex.Message);
+ dispWidth = dispHeight = 1;
+ }
+ } else if (vis is VisWireframeAnimation) {
+ AnimatedGifEncoder encoder = new AnimatedGifEncoder();
+ ((VisWireframeAnimation)vis).EncodeGif(encoder, IMAGE_SIZE);
+
+ // Create new or replace existing image file.
+ fileName += "_ani.gif";
+ string pathName = Path.Combine(mImageDirPath, fileName);
+ try {
+ using (FileStream stream = new FileStream(pathName, FileMode.Create)) {
+ encoder.Save(stream, out dispWidth, out dispHeight);
+ }
+ } catch (Exception ex) {
+ // TODO: add an error report
+ Debug.WriteLine("Error creating animated WF GIF file '" + pathName +
+ "': " + ex.Message);
dispWidth = dispHeight = 1;
}
} else {
diff --git a/SourceGen/SGTestData/Visualization/wireframe-test.dis65 b/SourceGen/SGTestData/Visualization/wireframe-test.dis65
index b861f34..c78de9b 100644
--- a/SourceGen/SGTestData/Visualization/wireframe-test.dis65
+++ b/SourceGen/SGTestData/Visualization/wireframe-test.dis65
@@ -267,13 +267,13 @@
"_isPerspective":true,
"_isBfcEnabled":true,
"_eulerRotX":0,
-"_eulerRotY":21,
-"_eulerRotZ":65,
+"_eulerRotY":0,
+"_eulerRotZ":0,
"_isAnimatedWireframe":true,
-"_deltaRotX":-6,
-"_deltaRotY":30,
+"_deltaRotX":3,
+"_deltaRotY":6,
"_deltaRotZ":0,
-"_frameCount":60,
+"_frameCount":120,
"_frameDelayMsec":100}},
{
@@ -291,14 +291,14 @@
"VisualizationAnimations":[{
"Tags":["wf_data",
"bmp_data"],
-"Tag":"anim00002c",
+"Tag":"ugly flash",
"VisGenIdent":"(animation)",
"VisGenParams":{
-"_frameDelayMsec":100}}],
+"_frameDelayMsec":1000}}],
"VisualizationSets":{
"10":{
"Tags":["wf_data",
"bmp_data"]},
"44":{
-"Tags":["anim00002c"]}}}
+"Tags":["ugly flash"]}}}
diff --git a/SourceGen/SourceGen.csproj b/SourceGen/SourceGen.csproj
index 886bd80..76891de 100644
--- a/SourceGen/SourceGen.csproj
+++ b/SourceGen/SourceGen.csproj
@@ -207,6 +207,9 @@
+
+ ShowWireframeAnimation.xaml
+
@@ -418,6 +421,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
diff --git a/SourceGen/VisWireframeAnimation.cs b/SourceGen/VisWireframeAnimation.cs
index 5e6a3ad..52242cf 100644
--- a/SourceGen/VisWireframeAnimation.cs
+++ b/SourceGen/VisWireframeAnimation.cs
@@ -17,7 +17,9 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
-
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using CommonWPF;
using PluginCommon;
namespace SourceGen {
@@ -51,18 +53,61 @@ namespace SourceGen {
private IVisualizationWireframe mVisWire;
+
+ ///
+ /// Constructor. Mostly pass-through, but we want to set the overlay image.
+ ///
public VisWireframeAnimation(string tag, string visGenIdent,
ReadOnlyDictionary visGenParams, Visualization oldObj,
IVisualizationWireframe visWire)
: base(tag, visGenIdent, visGenParams, oldObj) {
// visWire may be null when loading from project file
mVisWire = visWire;
+ OverlayImage = ANIM_OVERLAY_IMAGE;
}
+ ///
+ /// Updates the thumbnail.
+ ///
+ ///
+ /// We override it because this is our first opportunity to capture the
+ /// IVisualizationWireframe reference when the object was created during project
+ /// file loading.
+ ///
+ /// Reference to wireframe data generated by plugin.
+ /// Render parameters.
public override void SetThumbnail(IVisualizationWireframe visWire,
ReadOnlyDictionary parms) {
base.SetThumbnail(visWire, parms);
mVisWire = visWire;
}
+
+ ///
+ /// Generates an animated GIF from a series of frames.
+ ///
+ /// GIF encoder.
+ /// Output dimensions.
+ public void EncodeGif(AnimatedGifEncoder encoder, double dim) {
+ int curX = Util.GetFromObjDict(VisGenParams, P_EULER_ROT_X, 0);
+ int curY = Util.GetFromObjDict(VisGenParams, P_EULER_ROT_Y, 0);
+ int curZ = Util.GetFromObjDict(VisGenParams, P_EULER_ROT_Z, 0);
+ int deltaX = Util.GetFromObjDict(VisGenParams, P_DELTA_ROT_X, 0);
+ int deltaY = Util.GetFromObjDict(VisGenParams, P_DELTA_ROT_Y, 0);
+ int deltaZ = Util.GetFromObjDict(VisGenParams, P_DELTA_ROT_Z, 0);
+ int frameCount = Util.GetFromObjDict(VisGenParams, P_FRAME_COUNT, 1);
+ int frameDelayMsec = Util.GetFromObjDict(VisGenParams, P_FRAME_DELAY_MSEC, 100);
+ bool doPersp = Util.GetFromObjDict(VisGenParams, VisWireframe.P_IS_PERSPECTIVE, true);
+ bool doBfc = Util.GetFromObjDict(VisGenParams, VisWireframe.P_IS_BFC_ENABLED, false);
+
+ for (int frame = 0; frame < frameCount; frame++) {
+ BitmapSource bs = GenerateWireframeImage(mVisWire, dim,
+ curX, curY, curZ, doPersp, doBfc);
+ encoder.AddFrame(BitmapFrame.Create(bs), frameDelayMsec);
+
+ curX = (curX + 360 + deltaX) % 360;
+ curY = (curY + 360 + deltaY) % 360;
+ curZ = (curZ + 360 + deltaZ) % 360;
+ }
+ }
}
}
diff --git a/SourceGen/Visualization.cs b/SourceGen/Visualization.cs
index e58fd7e..9d51c5e 100644
--- a/SourceGen/Visualization.cs
+++ b/SourceGen/Visualization.cs
@@ -196,7 +196,7 @@ namespace SourceGen {
ReadOnlyDictionary parms) {
Debug.Assert(visWire != null);
Debug.Assert(parms != null);
- CachedImage = GenerateWireframeImage(visWire, parms, THUMBNAIL_DIM);
+ CachedImage = GenerateWireframeImage(visWire, THUMBNAIL_DIM, parms);
}
///
@@ -254,13 +254,28 @@ namespace SourceGen {
/// and GIF exports.
///
/// Visualization data.
- /// Parameter set, for rotations and render options.
/// Output bitmap dimension (width and height).
+ /// Parameter set, for rotations and render options.
/// Rendered bitmap.
public static BitmapSource GenerateWireframeImage(IVisualizationWireframe visWire,
- ReadOnlyDictionary parms, double dim) {
+ double dim, ReadOnlyDictionary parms) {
+ 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 doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false);
+ return GenerateWireframeImage(visWire, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
+ }
+
+ ///
+ /// Generates a BitmapSource from IVisualizationWireframe data. Useful for thumbnails
+ /// and GIF exports.
+ ///
+ public static BitmapSource GenerateWireframeImage(IVisualizationWireframe visWire,
+ double dim, int eulerX, int eulerY, int eulerZ, bool doPersp, bool doBfc) {
// Generate the path geometry.
- GeometryGroup geo = GenerateWireframePath(visWire, parms, dim);
+ GeometryGroup geo = GenerateWireframePath(visWire, dim, eulerX, eulerY, eulerZ,
+ doPersp, doBfc);
// Render Path to bitmap -- https://stackoverflow.com/a/23582564/294248
Rect bounds = geo.GetRenderBounds(null);
@@ -302,14 +317,25 @@ namespace SourceGen {
/// coordinates so they fit within the box.
///
/// Visualization data.
- /// Visualization parameters.
/// Width/height to use for path area.
+ /// Visualization parameters.
public static GeometryGroup GenerateWireframePath(IVisualizationWireframe visWire,
- ReadOnlyDictionary parms, double dim) {
+ double dim, ReadOnlyDictionary parms) {
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 doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false);
+ return GenerateWireframePath(visWire, dim, eulerX, eulerY, eulerZ, doPersp, doBfc);
+ }
+ ///
+ /// Generates WPF Path geometry from IVisualizationWireframe data. Line widths get
+ /// scaled if the output area is larger or smaller than the path bounds, so this scales
+ /// coordinates so they fit within the box.
+ ///
+ public static GeometryGroup GenerateWireframePath(IVisualizationWireframe visWire,
+ double dim, int eulerX, int eulerY, int eulerZ, bool doPersp, bool doBfc) {
// WPF path drawing is based on a system where a pixel is drawn at the center
// of the coordinate, and integer coordinates start at the top left edge. If
// you draw a pixel at (0,0), most of the pixel will be outside the window
@@ -352,7 +378,8 @@ namespace SourceGen {
// Generate a list of clip-space line segments. Coordinate values are in the
// range [-1,1], with +X to the right and +Y upward.
WireframeObject wireObj = WireframeObject.Create(visWire);
- List segs = wireObj.Generate(parms, eulerX, eulerY, eulerZ);
+ List segs = wireObj.Generate(eulerX, eulerY, eulerZ,
+ doPersp, doBfc);
// Convert clip-space coords to screen. We need to translate to [0,2] with +Y
// toward the bottom of the screen, scale up, round to the nearest whole pixel,
diff --git a/SourceGen/WireframeObject.cs b/SourceGen/WireframeObject.cs
index 2c6598f..e80c339 100644
--- a/SourceGen/WireframeObject.cs
+++ b/SourceGen/WireframeObject.cs
@@ -206,14 +206,16 @@ namespace SourceGen {
/// Generates a list of line segments for the wireframe data and the specified
/// parameters.
///
- /// Visualization parameters.
- /// List of line segments, which could be empty if backface removal
+ /// Rotation about X axis.
+ /// Rotation about Y axis.
+ /// Rotation about Z axis.
+ /// Perspective or othographic projection?
+ /// Perform backface culling?
+ /// List a of line segments, which could be empty if backface culling
/// was especially successful.
- public List Generate(ReadOnlyDictionary parms,
- int eulerX, int eulerY, int eulerZ) {
+ public List Generate(int eulerX, int eulerY, int eulerZ,
+ bool doPersp, bool doBfc) {
List segs = new List(mEdges.Count);
- bool doPersp = Util.GetFromObjDict(parms, VisWireframe.P_IS_PERSPECTIVE, false);
- bool doBfc = Util.GetFromObjDict(parms, VisWireframe.P_IS_BFC_ENABLED, false);
// Camera Z coordinate adjustment, used to control how perspective projections
// appear. The larger the value, the farther the object appears to be. Very
diff --git a/SourceGen/WpfGui/EditVisualization.xaml b/SourceGen/WpfGui/EditVisualization.xaml
index 2da6f81..35ac87a 100644
--- a/SourceGen/WpfGui/EditVisualization.xaml
+++ b/SourceGen/WpfGui/EditVisualization.xaml
@@ -255,8 +255,8 @@ limitations under the License.
-