You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.9KB

  1. #ifndef GONIOMETERCONTROL_H_INCLUDED
  2. #define GONIOMETERCONTROL_H_INCLUDED
  3. #include "JuceHeader.h"
  4. #include "TomatlImageType.h"
  5. #include "dsp-utility.h"
  6. #include "ILateInitComponent.h"
  7. //==============================================================================
  8. /*
  9. */
  10. class GoniometerControl : public ILateInitComponent
  11. {
  12. private:
  13. Image mContent;
  14. Image mBackground;
  15. Image mSurface;
  16. AdmvAudioProcessor* mParentProcessor;
  17. void initLayers()
  18. {
  19. Graphics buffer(mContent);
  20. buffer.setColour(Colours::transparentBlack);
  21. buffer.fillAll();
  22. int margin = 4;
  23. float sqrt2 = std::sqrt(2);
  24. juce::Point<float> center(getWidth() / 2, getHeight() / 2);
  25. float lineScaleX = (getWidth()) / 2 - margin;
  26. float lineScaleY = (getHeight()) / 2 - margin;
  27. Line<float> leftDiag(movePoint<float>(center, -lineScaleX / sqrt2, -lineScaleY / sqrt2), movePoint<float>(center, +lineScaleX / sqrt2, +lineScaleY / sqrt2));
  28. Line<float> rightDiag(movePoint<float>(center, -lineScaleX / sqrt2, +lineScaleY / sqrt2), movePoint<float>(center, +lineScaleX / sqrt2, -lineScaleY / sqrt2));
  29. Graphics background(mBackground);
  30. background.setImageResamplingQuality(Graphics::ResamplingQuality::highResamplingQuality);
  31. background.setColour(Colour::fromString("FF101010"));
  32. background.fillAll();
  33. background.setColour(Colour::fromString("FF202020"));
  34. background.drawEllipse(margin, margin, getWidth() - margin * 2, getHeight() - margin * 2, 1.5);
  35. background.drawLine(leftDiag);
  36. background.drawLine(rightDiag);
  37. background.setColour(Colours::darkgrey);
  38. background.drawRect(getLocalBounds(), 2.f);
  39. background.setColour(Colours::black);
  40. background.drawRect(getLocalBounds().expanded(-1.), 1.f);
  41. }
  42. public:
  43. virtual void init(juce::Rectangle<int> bounds)
  44. {
  45. setOpaque(true);
  46. setPaintingIsUnclipped(false);
  47. setSize(bounds.getWidth(), bounds.getHeight());
  48. mContent = Image(Image::ARGB, getWidth(), getHeight(), true, TomatlImageType());
  49. mBackground = Image(Image::RGB, getWidth(), getHeight(), true, TomatlImageType());
  50. mSurface = Image(Image::RGB, getWidth(), getHeight(), true, TomatlImageType());
  51. initLayers();
  52. }
  53. template <typename T> juce::Point<T> movePoint(juce::Point<T> source, T x, T y)
  54. {
  55. juce::Point<T> newPoint(source);
  56. newPoint.addXY(x, y);
  57. return newPoint;
  58. }
  59. GoniometerControl(AdmvAudioProcessor* parentPlugin)
  60. {
  61. mParentProcessor = parentPlugin;
  62. }
  63. ~GoniometerControl()
  64. {
  65. }
  66. void paint (Graphics& g)
  67. {
  68. Graphics buffer(mContent);
  69. Image::BitmapData pixels(mContent, Image::BitmapData::ReadWriteMode::readWrite);
  70. // TODO: split to several smaller methods
  71. for (size_t cn = 0; cn < mParentProcessor->getMaxStereoPairCount(); ++cn)
  72. {
  73. if (mParentProcessor->mGonioSegments == NULL)
  74. {
  75. break;
  76. }
  77. GonioPoints<double> segment = mParentProcessor->mGonioSegments[cn];
  78. double totalDistance = 0;
  79. Path p;
  80. if (segment.mLength <= 0)
  81. {
  82. continue;
  83. }
  84. if (segment.mFramesRendered > TOMATL_FPS)
  85. {
  86. continue;
  87. }
  88. mParentProcessor->mGonioSegments[cn].mFramesRendered += 1;
  89. double x = TOMATL_BOUND_VALUE((int)((segment.mData[0].first + 1.) * getWidth() / 2.), 0, getWidth() - 1);
  90. double y = TOMATL_BOUND_VALUE((int)((segment.mData[0].second + 1.) * getHeight() / 2.), 0, getHeight() - 1);
  91. p.startNewSubPath(x, y);
  92. std::vector<std::pair<double, double>> points;
  93. points.push_back(std::pair<double, double>(x, y));
  94. for (size_t i = 1; i < segment.mLength - 1; ++i)
  95. {
  96. double x = TOMATL_BOUND_VALUE((segment.mData[i].first + 1.) * getWidth() / 2., 0., getWidth() - 1.);
  97. double y = TOMATL_BOUND_VALUE((segment.mData[i].second + 1.) * getHeight() / 2., 0., getHeight() - 1.);
  98. std::pair<double, double> prev = points[points.size() - 1];
  99. double distance = std::sqrt(std::pow(prev.first - x, 2) + std::pow(prev.second - y, 2));
  100. totalDistance += distance;
  101. if (distance > 20)
  102. {
  103. //p.quadraticTo(prev.first, prev.second, x, y);
  104. //p.addLineSegment(Line<float>(prev.first, prev.second, x, y), 0.7);
  105. points.push_back(std::pair<double, double>(x, y));
  106. }
  107. }
  108. juce::Colour srcColor = mParentProcessor->getStereoPairColor(segment.mIndex);
  109. tomatl::draw::ColorARGB color;
  110. color.fromColor(srcColor);
  111. if (points.size() > 4)
  112. {
  113. for (size_t i = 0; i < points.size() - 3; i += 3)
  114. {
  115. std::pair<double, double> p1 = points[i + 0];
  116. std::pair<double, double> p2 = points[i + 1];
  117. std::pair<double, double> p3 = points[i + 2];
  118. std::pair<double, double> p4 = points[i + 3];
  119. tomatl::draw::Util::cubic_bezier(
  120. p1.first, p1.second,
  121. p2.first, p2.second,
  122. p3.first, p3.second,
  123. p4.first, p4.second,
  124. pixels, color);
  125. //pixels.setPixelColour(points[i].first, points[i].second, Colours::green);
  126. //p.lineTo(points[i].first, points[i].second);
  127. //p.quadraticTo(points[i].first, points[i].second, points[i + 1].first, points[i + 1].second);
  128. }
  129. }
  130. p.closeSubPath();
  131. //buffer.setColour(mParentProcessor->getStereoPairColor(segment.mIndex));
  132. //mContent.multiplyAllAlphas(0.95);
  133. }
  134. uint8 alpha = 242;
  135. uint16 reg;
  136. // Decay
  137. // TODO: move to CustomDrawing
  138. for (int i = 0; i < pixels.height; ++i)
  139. {
  140. uint8* line = pixels.getLinePointer(i);
  141. for (int j = 0; j < pixels.width * pixels.pixelStride; ++j)
  142. {
  143. reg = line[j] * alpha;
  144. line[j] = TOMATL_FAST_DIVIDE_BY_255(reg);
  145. }
  146. }
  147. #if TOMATL_CUSTOM_BLENDING
  148. tomatl::draw::Util::blend(mBackground, mContent, mSurface);
  149. g.drawImageAt(mSurface, 0, 0, false);
  150. #else
  151. g.drawImageAt(mBackground, 0, 0);
  152. g.drawImageAt(mContent, 0, 0);
  153. #endif
  154. }
  155. void resized()
  156. {
  157. // This contol doesn't support resizing ATM
  158. }
  159. private:
  160. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GoniometerControl)
  161. };
  162. #endif // GONIOMETERCONTROL_H_INCLUDED