// renders the given node to the internal ElementData dictionary. If the given node is // not a element, will recursively descend until we render its elements. private void RenderNode(IElementNode node) { int wid; int ht; if (_data.NutcrackerData.StringOrienation == NutcrackerEffects.StringOrientations.Horizontal) { wid = MaxPixelsPerString; ht = StringCount; } else { wid = StringCount; ht = MaxPixelsPerString; } int nFrames = (int)(TimeSpan.TotalMilliseconds / frameMs); if (nFrames <= 0) { return; } var nccore = new NutcrackerEffects(_data.NutcrackerData) { Duration = TimeSpan }; nccore.InitBuffer(wid, ht); int numElements = node.Count(); TimeSpan startTime = TimeSpan.Zero; // OK, we're gonna create 1 intent per element // that intent will hold framesToRender Color values // that it will parcel out as intent states are called for... // set up arrays to hold the generated colors var pixels = new RGBValue[numElements][]; for (int eidx = 0; eidx < numElements; eidx++) { pixels[eidx] = new RGBValue[nFrames]; } // generate all the pixels for (int frameNum = 0; frameNum < nFrames; frameNum++) { nccore.RenderNextEffect(_data.NutcrackerData.CurrentEffect); // peel off this frames pixels... if (_data.NutcrackerData.StringOrienation == NutcrackerEffects.StringOrientations.Horizontal) { int i = 0; for (int y = 0; y < ht; y++) { for (int x = 0; x < _stringPixelCounts[y]; x++) { pixels[i][frameNum] = new RGBValue(nccore.GetPixel(x, y)); i++; } } } else { int i = 0; for (int x = 0; x < wid; x++) { for (int y = 0; y < _stringPixelCounts[x]; y++) { pixels[i][frameNum] = new RGBValue(nccore.GetPixel(x, y)); i++; } } } } ; // create the intents var frameTs = new TimeSpan(0, 0, 0, 0, frameMs); List <Element> elements = node.ToList(); for (int eidx = 0; eidx < numElements; eidx++) { IIntent intent = new StaticArrayIntent <RGBValue>(frameTs, pixels[eidx], TimeSpan); _elementData.AddIntentForElement(elements[eidx].Id, intent, startTime); } nccore.Dispose(); }