Thursday, October 27, 2005
objects needing more comments
ctrlresize, replacefilesdlg, masterdlg, parmrow, playlist, numbersdlg, viewdialog
Tuesday, October 25, 2005
adding HLS color to existing snapshots
ar << sizeof(RING);
ar << m_Ring.GetCount();
POSITION pos = m_Ring.GetHeadPosition();
for (int i = 0; i < m_Ring.GetCount(); i++) {
RING rp = m_Ring.GetNext(pos);
double h, l, s;
int c = rp.Color;
CHLS::rgb2hls(GetRValue(c) / 255.0,
GetGValue(c) / 255.0, GetBValue(c) / 255.0, h, l, s);
rp.Hue = h;
rp.Lightness = l;
rp.Saturation = s;
ar.Write(&rp, sizeof(RING));
}
Monday, October 24, 2005
Movie format could save space
The movies are using the snapshot format, which includes all of the ring info. In the ring info, the rotation and shift deltas and the HLS color are not used at all during movie playback. These attributes constitute 40 bytes out of 120, or one third of the total size of the ring structure. The actual savings could be nearly a third, since most of the space in a movie is taken up by rings (hundreds of rings per frame).
The savings would require adding a second serialization method, e.g. MiniSerialize, which would be used by the SnapMovie object. The method could be optimized by placing the deltas and the HLS color at the start of the ring structure, because then it would still be possible to do a single write directly from the ring, instead of copying to an intermediate structure first.
A problem with this approach is that it would longer be possible to export a complete (non-mini) snapshot from a movie, since some of the information would be missing. The HLS color could be restored from RGB, but not the deltas. On the other hand the deltas aren't useful in snapshots so maybe it wouldn't matter.
NOTE that WinZip reduces Steve1.whm by 61%, and Steve2.whm by 73%.
Space-saving benchmarks:
60 seconds, 25 FPS, default speed, window maximized but not full-screen, wait for full ring count before starting to record, sizes in MB, ring counts are rough averages
useful nugget of ring conversion code:
The savings would require adding a second serialization method, e.g. MiniSerialize, which would be used by the SnapMovie object. The method could be optimized by placing the deltas and the HLS color at the start of the ring structure, because then it would still be possible to do a single write directly from the ring, instead of copying to an intermediate structure first.
A problem with this approach is that it would longer be possible to export a complete (non-mini) snapshot from a movie, since some of the information would be missing. The HLS color could be restored from RGB, but not the deltas. On the other hand the deltas aren't useful in snapshots so maybe it wouldn't matter.
NOTE that WinZip reduces Steve1.whm by 61%, and Steve2.whm by 73%.
Space-saving benchmarks:
60 seconds, 25 FPS, default speed, window maximized but not full-screen, wait for full ring count before starting to record, sizes in MB, ring counts are rough averages
patch rings old new less
kaleid 1000 172.5 108.8 37%
pinwheel 500 98.0 62.5 36%
lotus light 300 71.4 46.5 35%
cross 150 34.6 26.3 24%
useful nugget of ring conversion code:
nr.RotDelta = rp.RotDelta;
nr.ShiftDelta = rp.ShiftDelta;
nr.Hue = rp.Hue;
nr.Lightness = rp.Lightness;
nr.Saturation = rp.Saturation;
nr.Rot = rp.Rot;
nr.Steps = rp.Steps;
nr.Scale = rp.Scale;
nr.Shift = rp.Shift;
nr.StarRatio = rp.StarRatio;
nr.Sides = rp.Sides;
nr.Delete = rp.Delete;
nr.Reverse = rp.Reverse;
nr.Color = rp.Color;
nr.Pinwheel = rp.Pinwheel;
nr.LineWidth = rp.LineWidth;
nr.DrawMode = rp.DrawMode;
nr.Spacing = rp.Spacing;
Thursday, October 20, 2005
array of CArrays not optimized correctly
It looks like dereferencing an array of CArray objects can causes MFC to call the [] operator, instead of inlining it, even in Release mode. Presumably this is why:
generates twice as much code as:
Oddly, this is bad too:
but this is fine (1 line longer than original):
int CPlaylistDlg::FindHotKey(DWORD HotKey) const
{
int Patches = GetCount();
for (int i = 0; i < Patches; i++) {
if (HotKey == m_Bank[m_CurBank][i].m_HotKey)
return(i);
}
return(-1);
}
generates twice as much code as:
int CPlaylistDlg::FindHotKey(DWORD HotKey) const
{
int Patches = GetCount();
for (int i = 0; i < Patches; i++) {
if (HotKey == (*m_Patch)[i].m_HotKey)
return(i);
}
return(-1);
}
Oddly, this is bad too:
int CPlaylistDlg::FindHotKey(DWORD HotKey) const
{
int Patches = GetCount();
const PATCH_LIST *p = &m_Bank[m_CurBank];
for (int i = 0; i < Patches; i++) {
if (HotKey == (*p)[i].m_HotKey)
return(i);
}
return(-1);
}
but this is fine (1 line longer than original):
int CPlaylistDlg::FindHotKey(DWORD HotKey) const
{
int Patches = GetCount();
for (int i = 0; i < Patches; i++) {
if (HotKey == m_Bank[m_CurBank].GetData()[i].m_HotKey)
return(i);
}
return(-1);
}
Saturday, October 08, 2005
MainFrame bloat
2662 lines and counting, ouch
non-message handlers 1139
message map 166
message handlers 1200
things that could move easily:
ShowDemo: only 32 lines but could get bigger
not so easy
GetInput: 83 lines and could get bigger
non-message handlers 1139
message map 166
message handlers 1200
things that could move easily:
ShowDemo: only 32 lines but could get bigger
not so easy
GetInput: 83 lines and could get bigger
odd shift
double xshift[2] = {rp.Shift.x * m_st.Zoom, (rp.Shift.x + rp.OddShift.x) * m_st.Zoom};
double yshift[2] = {rp.Shift.y * m_st.Zoom, (rp.Shift.y + rp.OddShift.y) * m_st.Zoom};
Notice that the calculation is NOT corrected for radius. This causes the effect to decrease with distance from the origin. Correcting for radius gives a very different and less pleasing effect. The display becomes too busy, and at extreme values, the image is distorted into a narrow cylinder. The first objection could possibly be addressed by limiting the size of the ring list.
To correct the above for radius:
double xshift[2] = {rp.Shift.x * m_st.Zoom, (rp.Shift.x + rp.OddShift.x * rp.Steps) * m_st.Zoom};
double yshift[2] = {rp.Shift.y * m_st.Zoom, (rp.Shift.y + rp.OddShift.y * rp.Steps) * m_st.Zoom};
Some possible names for "odd shift":
Shear: incorrect usage
Extrude: incorrect usage
Tilt: too vague
Tunnel: too vague, also other parameters can produce this effect
Relief: too vague
Stamen: too obscure
Center Fold: misleading, the new version corrects for radius, see below
Splay: means legs spread at various angles, not various lengths
Deform: vague, not a noun, misleading negative connotations
Bias: misleading connotation of unfairness
Fold: vague, possibly misleading
Asymmetry: vague, too long a word
10/29/05 corrected for radius but also centered, much better
DPOINT splay = {rp.Splay.x * rp.Steps, rp.Splay.y * rp.Steps};
double xshift[2] = {
(rp.Shift.x - splay.x) * m_st.Zoom,
(rp.Shift.x + splay.x) * m_st.Zoom};
double yshift[2] = {
(rp.Shift.y - splay.y) * m_st.Zoom,
(rp.Shift.y + splay.y) * m_st.Zoom};
Controls should be polar as with Skew: Splay Radius, Splay Angle
Some interesting interdependent terms:
Contort: Twist, wrench, or bend severely out of shape
Pinch: To press, squeeze, or bind painfully
Buckle: Bending, warping, or crumpling; a bend or bulge
Rumple: An irregular or untidy crease
Crumple: To crush together or press into wrinkles; rumple
Crease: A line made by pressing, folding, or wrinkling
Wrinkle: A small furrow, ridge, or crease on a normally smooth surface
Pucker: To gather into small wrinkles or folds
And the winner as of 12/17/05 is:
PUCKER
totally cool demo: default patch, ring spacing 11.192, pucker radius -.406, pucker angle -65.88 / ramp up / 180 / .08, master speed 222
another one: patch_051028050234, rings = 75, pucker rad = .268, angle = ramp up / 180 / .5, speed = 495
optimized 12/19/05 (two less Zoom multiplications):
DPOINT pucker = {rp.Pucker.x * steps, rp.Pucker.y * steps};
DPOINT shift = {rp.Shift.x * m_st.Zoom, rp.Shift.y * m_st.Zoom};
double xshift[2] = {shift.x - pucker.x, shift.x + pucker.x};
double yshift[2] = {shift.y - pucker.y, shift.y + pucker.y};
ring list size limit
in AddRing, at the very end:
while (m_Ring.GetCount() > whatever) {
if (Ring.Reverse)
m_Ring.RemoveHead();
else
m_Ring.RemoveTail();
}
Bézier curves
in Draw:
#if 1
m_pa[i] = m_pa[0]; // close the shape
Polyline(dc, m_pa, sides + 1);
#else
CPoint pt2[200];
int j = 0;
for (int i = 0; i < sides; i++) {
pt2[j++] = m_pa[i];
if (i & 1)
pt2[j++] = CPoint(m_pa[i].x, m_pa[i].y);
}
pt2[j++] = pt2[0];
PolyBezier(dc, pt2, j);
#endif
Saturday, October 01, 2005
scene rotation
in DefState:
0 // Rotation
in Addring:
Ring.Rot = Ring.RotDelta * Offset + m_st.Rotation;
void CWhorldView::Rotate(double Degrees, bool Repaint)
{
POSITION pos = m_Ring.GetHeadPosition();
double r = DTR(Degrees);
while (pos != NULL) {
RING& Ring = m_Ring.GetNext(pos);
Ring.Rot += r;
}
m_st.Rotation = fmod(m_st.Rotation + r, 2 * PI); // wrap to limit magnitude
if (Repaint)
Invalidate();
}
Note that this causes unexpected behavior (addition, subtraction, cancelation) when rotation is inverse of LFO rotation. Also X/Y shifts are NOT rotated, so for example if Aspect Ratio is 2, the asymmetry will remain orthogonal instead of rotating. Solving this would require changes to the drawing code.
benchmarks for movie recording
------------
PIII, Kaleid, 1024 x 768, 30 FPS, speed = 680, 2500 samps: min = .001197, max = .004851, avg = .001821, sdev = .000362
avg .002 = .06 @ second = 6% avg usage for recording
-----------
AMD, Kaleid, 1024 x 768, 30 FPS, speed = 680, 2500 samps: min = .000167, max = .000611, avg = .000322, sdev = 8.8329E-05
avg .0003 = .009 @ second = .9% avg usage for recording
------------
AMD test repeated over 5 minutes: min = .000172, max = .005491, avg = .000485, sdev = .000129
all samples were < than 1 ms except for a single single spike of 0.005491 at 3:38
------------
PIII, Kaleid, 1024 x 768, 30 FPS, speed = 680, 2500 samps: min = .001197, max = .004851, avg = .001821, sdev = .000362
avg .002 = .06 @ second = 6% avg usage for recording
-----------
AMD, Kaleid, 1024 x 768, 30 FPS, speed = 680, 2500 samps: min = .000167, max = .000611, avg = .000322, sdev = 8.8329E-05
avg .0003 = .009 @ second = .9% avg usage for recording
------------
AMD test repeated over 5 minutes: min = .000172, max = .005491, avg = .000485, sdev = .000129
all samples were < than 1 ms except for a single single spike of 0.005491 at 3:38
------------
glitch #1: Jeff & Sean
Sean:
1. Visible tearing of image: DirectX is supposed to care of this no? Would full-screen mode affect it? Possibly affected by frame rate and CPU loading.
2. Should sync to beat automatically.
3. Should support multiple trackballs and other input devices at once.
Jeff:
1. Support for MIDI notes would be helpful since he's using an Oxygen 8. Notes could act as toggles for the function keys.
2. Tempo nudge should NOT resync, or at least there should be an alternate nudge that doesn't resync. Sean agrees.
3. Rotation of the entire image (as opposed to rotate speed), especially via MIDI.
4. Zoom should go further out: can do this with MIDI.
1. Visible tearing of image: DirectX is supposed to care of this no? Would full-screen mode affect it? Possibly affected by frame rate and CPU loading.
2. Should sync to beat automatically.
3. Should support multiple trackballs and other input devices at once.
Jeff:
1. Support for MIDI notes would be helpful since he's using an Oxygen 8. Notes could act as toggles for the function keys.
2. Tempo nudge should NOT resync, or at least there should be an alternate nudge that doesn't resync. Sean agrees.
3. Rotation of the entire image (as opposed to rotate speed), especially via MIDI.
4. Zoom should go further out: can do this with MIDI.
Subscribe to:
Posts (Atom)