Пример #1
0
        public SliderNode(
            AParentSceneNode parent,
            Transform localTransform,
            // what parameter does this slider drag?
            Parameter parameter,
            // at what angle is the slider oriented?
            float rotation,
            // how long is the slider in screen space?
            int screenLength,
            // how far is the slider's origin from the transform's translation, in screen space?
            int originScreenOffset,
            // what is the slider's label?
            string label)
            : base(parent, localTransform, label)
        {
            m_parameter = parameter;
            m_rotation = rotation;
            m_screenLength = screenLength;
            m_originScreenOffset = originScreenOffset;

            // calculate the endpoints
            m_zeroEnd = ValueToLocal(0);
            m_oneEnd = ValueToLocal(1);

            double absRotation = Math.IEEERemainder(rotation, Math.PI * 2);
            if (absRotation < 0) {
                absRotation += Math.PI * 2;
            }

            m_label = new TextNode(this, label + "_text");

            bool overPi = absRotation > Math.PI;

            m_label.Alignment = overPi ? Alignment.TopLeft : Alignment.TopRight;
            m_label.Text.Append(label);
            m_label.LocalTransform = new Transform(m_oneEnd, new Vector2(0.7f));
            // seems the line rotation and label rotation go in opposite directions, feh!
            m_label.Rotation = -rotation + (float)(Math.PI / 2) + (overPi ? (float)Math.PI : 0);

            m_fullLine = new LineNode(this, "fullLine");
            m_fullLine.SetEndpoints(m_zeroEnd, m_oneEnd);

            m_sliderLine = new LineNode(this, "sliderLine");
            m_sliderLine.LocalTransform = new Transform(Vector2.Zero, new Vector2(3f)); // 3-pixel wide line

            Value = m_parameter[0];
        }
Пример #2
0
 public BeatNode(
     AParentSceneNode parent,
     Transform localTransform,
     string label,
     // are we filling in every beat, or just the current beat?
     bool fillInEveryBeat,
     // by how much do we scale down our texture when rendering a quarter note?
     float textureScale,
     Func<Duration<Sample>> trackLengthFunc,
     Func<int> initialBeatFunc,
     Func<Color> colorFunc)
     : base(parent, localTransform, label)
 {
     m_fillInEveryBeat = fillInEveryBeat;
     m_textureScale = textureScale;
     m_trackLengthFunc = trackLengthFunc;
     m_initialBeatFunc = initialBeatFunc;
     m_colorFunc = colorFunc;
 }
Пример #3
0
        public TextSpriteNode(
            AParentSceneNode parent,
            Transform localTransform,
            string label,
            Texture2D background,
            Texture2D highlight)
            : base(parent, localTransform, label)
        {
            m_spriteNode = new SpriteNode(this, label + "_sprite", background);
            m_spriteNode.Origin = new Vector2(0.5f);

            m_textNode = new TextNode(this, label + "_text");
            m_textNode.Alignment = Alignment.Centered;
            m_textNode.Text.Append(label);
            m_textNode.LocalTransform = new Transform(Vector2.Zero, new Vector2(0.6f));

            m_highlightSpriteNode = new SpriteNode(this, label + "_highlight", highlight);
            m_highlightSpriteNode.Origin = new Vector2(0.5f);
        }
Пример #4
0
        protected override void DoRender(
            Moment now,
            GraphicsDevice graphicsDevice,
            ISpriteBatch spriteBatch,
            TextureContent content,
            HolofunkView view,
            Transform parentTransform,
            int depth)
        {
            bool positionMirrored =
                SecondaryViewOption == SecondaryViewOption.PositionMirrored
                && view == HolofunkView.Secondary;

            Vector2 p0 = m_p0 + parentTransform.Translation;
            Vector2 p1 = m_p1 + parentTransform.Translation;

            if (positionMirrored) {
                p0 = new Vector2(spriteBatch.Viewport.X - p0.X, p0.Y);
                p1 = new Vector2(spriteBatch.Viewport.X - p1.X, p1.Y);
            }

            Vector2 diff = Vector2.Subtract(p1, p0);
            float angleRadians = (float)Math.Atan2(diff.Y, diff.X);
            float length = (float)Math.Sqrt(diff.X * diff.X + diff.Y * diff.Y) / 2;

            // Use NonPremultiplied, as our sprite textures are not premultiplied
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);

            spriteBatch.Draw(
                content.TinyDot,
                p0,
                null,
                Color,
                angleRadians,
                new Vector2(0f, 1f), // we pivot around the center of the left edge of the 2x2 square
                new Vector2(length, LocalTransform.Scale.Y),
                SpriteEffects.None,
                0);

            spriteBatch.End();
        }
Пример #5
0
        internal TrackNode(
            AParentSceneNode parent,
            Transform transform,
            string label,
            TextureContent content,
            int id,
            SparseSampleByteStream videoStream,
            bool fillInEveryBeat,
            Func<float> levelRatioFunc,
            Func<Color> circleColorFunc,
            Func<Color> videoColorFunc,
            Func<Duration<Sample>> trackDurationFunc,
            Func<int> initialBeatFunc,
            Func<Color> beatColorFunc,
            Func<float> videoRateFunc)
            : base(parent, transform, label)
        {
            m_id = id;

            m_levelRatioFunc = levelRatioFunc;
            m_circleColorFunc = circleColorFunc;
            m_videoColorFunc = videoColorFunc;
            m_beatColorFunc = beatColorFunc;
            m_videoRateFunc = videoRateFunc;

            // create this first so it is Z-ordered behind m_soundNode
            m_selectNode = new SpriteNode(this, "TrackHighlight", content.FilledCircle);
            m_selectNode.Color = new Color((byte)0x80, (byte)0x80, (byte)0x80, (byte)0x80);
            m_selectNode.Origin = new Vector2(0.5f);

            m_soundNode = new SpriteNode(this, "TrackSound", content.FilledCircle);
            m_soundNode.Color = Color.Blue;
            m_soundNode.Origin = new Vector2(0.5f);

            m_videoNode = new SpriteNode(this, "Headshot", content.NewDynamicTexture(MagicNumbers.HeadCaptureSize, MagicNumbers.HeadCaptureSize));
            m_videoNode.Origin = new Vector2(0.5f);
            m_videoNode.LocalTransform = new Transform(new Vector2(0), new Vector2(MagicNumbers.HeadRatio));
            m_videoNode.SetSecondaryViewOption(SecondaryViewOption.TextureMirrored);

            m_videoStream = videoStream;

            m_beatNode = new BeatNode(
                this,
                // move it down a bit from the sprite node
                new Transform(new Vector2(0, 75)),
                "TrackBeats",
                fillInEveryBeat,
                MagicNumbers.MeasureCircleScale,
                trackDurationFunc,
                initialBeatFunc,
                beatColorFunc);

            m_beatNode.SetSecondaryViewOption(SecondaryViewOption.PositionMirrored);

            // we always mirror track node position
            SetSecondaryViewOption(SecondaryViewOption.PositionMirrored);

            m_lastVideoFrame = default(Slice<Frame, byte>);
        }
Пример #6
0
        protected override void DoRender(Moment now, GraphicsDevice graphicsDevice, ISpriteBatch spriteBatch, TextureContent content, HolofunkView view, Transform parentTransform, int depth)
        {
            m_videoRateCounter += m_videoRateFunc();
            if (m_videoRateCounter >= 1f) {
                m_videoRateCounter -= 1f;
                lock (this) {
                    if (VideoStream != null) {
                        s_totalRenders++;

                        Slice<Frame, byte> videoImage = VideoStream.GetClosestSliver(now.Time + MagicNumbers.LatencyCompensationDuration);

                        if (!videoImage.IsEmpty()) {
                            if (videoImage.Equals(m_lastVideoFrame)) {
                                // skip the setData
                                s_redundantSetDatas++;
                            }
                            else {
                                // blast the data in there with a single pointer-based memory copy
                                videoImage.RawAccess((array, offset, count) => m_videoNode.Texture.SetData(array, (int)offset, (int)count));
                                m_lastVideoFrame = videoImage;
                            }
                        }
                    }
                    else {
                        // ain't nothing to show
                        m_videoNode.Texture.SetData(BlankTextureData);
                    }
                }
            }

            base.DoRender(now, graphicsDevice, spriteBatch, content, view, parentTransform, depth);
        }
Пример #7
0
 /// <summary>Combine the two transforms by adding their translations and multiplying their scales,
 /// WITHOUT scaling their translations in any way.</summary>
 public Transform CombineWith(Transform other)
 {
     return new Transform(Translation + other.Translation, Scale * other.Scale);
 }
Пример #8
0
        /// <summary>Render this AParentSceneNode by rendering all its children.</summary>
        protected override void DoRender(
            Moment now,
            GraphicsDevice graphicsDevice, 
            ISpriteBatch spriteBatch,
            TextureContent content,
            HolofunkView view,
            Transform parentTransform, 
            int depth)
        {
            Transform combinedTransform = parentTransform.CombineWith(LocalTransform);

            if (view == HolofunkView.Secondary && SecondaryViewOption == SecondaryViewOption.PositionMirrored) {
                combinedTransform = new Transform(
                    new Vector2(
                        spriteBatch.Viewport.X - combinedTransform.Translation.X,
                        combinedTransform.Translation.Y),
                    combinedTransform.Scale);
            }

            Spam.Graphics.WriteLine(new string(' ', depth * 4) + Label + ": parentTransform " + parentTransform + ", localTransform " + LocalTransform + ", combinedTransform " + combinedTransform);

            // m_children must only be enumerated / mutated under lock (this)
            lock (this) {
                m_childSnapshot.AddRange(m_children);
            }

            for (int i = 0; i < m_childSnapshot.Count; i++) {
                m_childSnapshot[i].Render(now, graphicsDevice, spriteBatch, content, view, combinedTransform, depth + 1);
            }

            // note that clearing preserves the capacity in the list, so no reallocation on next render
            m_childSnapshot.Clear();
        }
Пример #9
0
 protected AParentSceneNode(AParentSceneNode parent, Transform localTransform, string label)
     : base(parent, localTransform, label)
 {
 }
Пример #10
0
        protected override void DoRender(
            Moment now,
            GraphicsDevice graphicsDevice, 
            ISpriteBatch spriteBatch,
            TextureContent content,
            HolofunkView view,
            Transform parentTransform, 
            int depth)
        {
            Transform combinedTransform = parentTransform.CombineWith(LocalTransform);

            spriteBatch.Begin();

            Vector2 textSize = content.SpriteFont.MeasureString(m_text);
            Vector2 origin = Vector2.Zero;

            if (Alignment == Alignment.Centered) {
                origin = textSize / 2;
            }
            else if (Alignment == Alignment.TopRight) {
                origin = new Vector2(textSize.X, 0);
            }

            spriteBatch.DrawString(
                content.SpriteFont,
                m_text,
                combinedTransform.Translation,
                Color,
                Rotation,
                origin,
                combinedTransform.Scale.X,
                SpriteEffects.None,
                0);

            spriteBatch.End();
        }
Пример #11
0
 /// <summary>
 /// Start recording a new loopie; return null if we have no free streams.
 /// </summary>
 internal Loopie StartRecording(Moment now, Transform handPosition, bool isRight)
 {
     Loopie ret = m_parent.StartRecordingNewLoopie(now, m_playerIndex, isRight, AsioChannel, handPosition);
     return ret;
 }
Пример #12
0
        protected override void DoRender(
            Moment now,
            GraphicsDevice graphicsDevice,
            ISpriteBatch spriteBatch,
            TextureContent content,
            HolofunkView view,
            Transform parentTransform,
            int depth)
        {
            if (m_totalBeats == 0) {
                // there is no actual track here; we do not render
                return;
            }

            Transform combinedTransform = parentTransform.CombineWith(LocalTransform);

            // How many measures?
            long measureCount = (m_totalBeats + 3) / 4;

            // note that the quarter-circle only takes up one quarter of quarterCircleRect; this is deliberate
            Rectangle quarterCircleRect = TextureRect(content.QuarterHollowCircle, combinedTransform.Scale * m_textureScale);

            Vector2 measuresOrigin = combinedTransform.Translation;
            measuresOrigin.X -= ((Math.Min(4, measureCount) * quarterCircleRect.Width) / 2);

            Color color = m_colorFunc();

            Spam.Graphics.WriteLine(new string(' ', depth * 4) + Label + ": parentTransform " + parentTransform + ", localTransform " + LocalTransform + ", combinedTransform " + combinedTransform + ", color " + color.ToString());

            for (int b = 0; b < m_totalBeats; b++) {
                float filledness;
                if (m_fillInEveryBeat) {
                    if (b < m_currentBeat) {
                        filledness = 1;
                    }
                    else if (b == m_currentBeat) {
                        filledness = (float)m_fractionalBeat;
                    }
                    else {
                        filledness = 0;
                    }
                }
                else {
                    if (b == m_currentBeat) {
                        filledness = (float)(1 - m_fractionalBeat);
                    }
                    else {
                        filledness = 0;
                    }
                }

                DrawQuarterCircle(spriteBatch, content, quarterCircleRect, measuresOrigin, b, color, filledness, depth);
            }
        }
Пример #13
0
 public GroupNode(AParentSceneNode parent, Transform localTransform, string label)
     : base(parent, localTransform, label)
 {
 }
Пример #14
0
 public SpriteBatchWrapper(SpriteBatch spriteBatch, Vector2 viewport, Transform transform)
 {
     m_spriteBatch = spriteBatch;
     m_viewport = viewport;
     m_transform = transform;
 }
Пример #15
0
        protected override void LoadContent()
        {
            base.LoadContent();

            float scale = GraphicsDevice.PresentationParameters.BackBufferHeight / m_viewportSize.Y;
            float scaledViewportWidth = m_viewportSize.X * scale;
            float scaledViewportOffset = (GraphicsDevice.PresentationParameters.BackBufferWidth - scaledViewportWidth) / 2;
            Transform transform = new Transform(new Vector2(scaledViewportOffset, 0), new Vector2(scale));

            m_spriteBatch = new SpriteBatchWrapper(new SpriteBatch(GraphicsDevice), ViewportSize, transform);

            var holofunkContent = new HolofunkTextureContent(Content, GraphicsDevice);

            m_model = new HolofunkModel(
                GraphicsDevice,
                m_clock,
                m_holofunkBass,
                m_kinect,
                holofunkContent,
                m_viewportSize,
                m_clock.BPM,
                m_audioAllocator,
                m_videoAllocator);
        }
Пример #16
0
        protected override void DoRender(
            Moment now,
            GraphicsDevice graphicsDevice, 
            ISpriteBatch spriteBatch,
            TextureContent content,
            HolofunkView view,
            Transform parentTransform,
            int depth)
        {
            // no texture = no-op
            if (m_texture == null) {
                return;
            }

            int left = -(int)((float)m_texture.Width * m_origin.X);
            int top = -(int)((float)m_texture.Height * m_origin.Y);
            Rectangle rect = new Rectangle(left, top, m_texture.Width, m_texture.Height);

            Transform combinedTransform = parentTransform.CombineWith(LocalTransform);

            Rectangle transformedRect = rect * combinedTransform;

            Spam.Graphics.WriteLine(new string(' ', depth * 4) + Label + ": parentTransform " + parentTransform + ", localTransform " + LocalTransform + ", combinedTransform " + combinedTransform + "; start rect " + rect.FormatToString() + "; transformedRect " + transformedRect.FormatToString());

            Texture2D texture = m_texture;
            SpriteEffects effects = SpriteEffects.None;

            if (view == HolofunkView.Secondary) {
                if ((SecondaryViewOption & SecondaryViewOption.TextureMirrored) != 0) {
                    effects = SpriteEffects.FlipHorizontally;
                }

                if ((SecondaryViewOption & SecondaryViewOption.PositionMirrored) != 0) {
                    // need to flip transformedRect around center of viewport
                    int newLeft = (int)spriteBatch.Viewport.X - transformedRect.Right;

                    transformedRect = new Rectangle(newLeft, transformedRect.Y, transformedRect.Width, transformedRect.Height);
                }

                if ((SecondaryViewOption & SecondaryViewOption.SecondTexture) != 0) {
                    HoloDebug.Assert(m_secondaryTexture != null);
                    texture = m_secondaryTexture;
                }
            }

            Color color = m_color;
            if (view == HolofunkView.Secondary && m_secondaryColor.HasValue) {
                color = m_secondaryColor.Value;
            }

            // Use NonPremultiplied, as our sprite textures are not premultiplied
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied);

            spriteBatch.Draw(
                texture,
                transformedRect,
                null,
                color,
                0,
                m_origin,
                effects,
                0);

            spriteBatch.End();
        }