da847a
da847a
da847a
// TnzTools includes
da847a
#include <tools replicator.h=""></tools>
da847a
#include <tools modifierjitter.h="" modifiers=""></tools>
da847a
da847a
da847a
// TnzCore includes
da847a
#include <tgl.h></tgl.h>
da847a
da847a
da847a
//*****************************************************************************************
da847a
//    TReplicatorJitter implementation
da847a
//*****************************************************************************************
da847a
da847a
class TReplicatorJitter final : public TReplicator {
da847a
  Q_DECLARE_TR_FUNCTIONS(TReplicatorJitter)
da847a
public:
da847a
  const TStringId m_idSkipFirst;
da847a
  const TStringId m_idPeriod;
da847a
  const TStringId m_idAmplitude;
da847a
da847a
protected:
da847a
  TAssistantPoint &m_center;
da847a
da847a
public:
da847a
  TReplicatorJitter(TMetaObject &object):
da847a
    TReplicator(object),
da847a
    m_idSkipFirst("skipFirst"),
da847a
    m_idPeriod("period"),
da847a
    m_idAmplitude("m_idAmplitude"),
da847a
    m_center( addPoint("center", TAssistantPoint::CircleCross) )
da847a
  {
da847a
    addProperty( createSpinProperty(m_idSkipFirst, getSkipFirst(), 0) );
da847a
da847a
    TDoubleProperty *p;
da847a
    
da847a
    p = new TDoubleProperty(m_idPeriod.str(), 0.0, 1000, getPeriod());
da847a
    p->setNonLinearSlider();
da847a
    addProperty(p);
da847a
da847a
    p = new TDoubleProperty(m_idAmplitude.str(), 0.0, 1000, getAmplitude());
da847a
    p->setNonLinearSlider();
da847a
    addProperty(p);
da847a
  }
da847a
da847a
  
da847a
  static QString getLocalName()
da847a
    { return tr("Jitter"); }
da847a
da847a
    
da847a
  void updateTranslation() const override {
da847a
    TReplicator::updateTranslation();
da847a
    setTranslation(m_idSkipFirst, tr("Skip First Tracks"));
da847a
    setTranslation(m_idPeriod, tr("Period"));
da847a
    setTranslation(m_idAmplitude, tr("Amplitude"));
da847a
  }
da847a
da847a
  
da847a
  inline int getSkipFirst() const
da847a
    { return (int)data()[m_idSkipFirst].getDouble(); }
da847a
  inline double getPeriod() const
da847a
    { return data()[m_idPeriod].getDouble(); }
da847a
  inline double getAmplitude() const
da847a
    { return data()[m_idAmplitude].getDouble(); }
da847a
da847a
protected:
da847a
  inline void setSkipFirst(int x)
da847a
    { if (getSkipFirst() != (double)x) data()[m_idSkipFirst].setDouble((double)x); }
da847a
  inline void setPeriod(double x)
da847a
    { if (getPeriod() != x) data()[m_idPeriod].setDouble(x); }
da847a
  inline void setAmplitude(double x)
da847a
    { if (getAmplitude() != x) data()[m_idAmplitude].setDouble(x); }
da847a
da847a
    
da847a
  void onSetDefaults() override {
da847a
    setPeriod(30);
da847a
    setAmplitude(10);
da847a
    TReplicator::onSetDefaults();
da847a
  }
da847a
da847a
  
da847a
  void onFixData() override {
da847a
    TReplicator::onFixData();
da847a
    setPeriod( std::max(0.0, std::min(1000.0, getPeriod())) );
da847a
    setAmplitude( std::max(0.0, std::min(1000.0, getAmplitude())) );
da847a
  }
da847a
da847a
  
da847a
  double getScale(const TAffine &a) const {
da847a
    return sqrt( a.a11*a.a11 + a.a12*a.a12
da847a
               + a.a21*a.a21 + a.a22*a.a22 )/2;
da847a
  }
da847a
    
da847a
public:
da847a
  
da847a
  void getPoints(const TAffine &toTool, PointList &points) const override {
da847a
    int skipFirst = getSkipFirst();
da847a
    if (skipFirst < 0) skipFirst = 0;
da847a
    if (skipFirst >= (int)points.size()) return;
da847a
    
da847a
    double scale = getScale(toTool);
da847a
    double period = getPeriod()*scale;
da847a
    double amplitude = getAmplitude()*scale;
da847a
    if (!(period > TConsts::epsilon && amplitude > TConsts::epsilon)) {
da847a
      int seedX = 0;
da847a
      int seedY = 7722441;
da847a
      for(PointList::iterator i = points.begin() + skipFirst; i != points.end(); ++i) {
da847a
        i->x += TModifierJitter::func(seedX, 0)*amplitude;
da847a
        i->y += TModifierJitter::func(seedY, 0)*amplitude;
da847a
        ++seedX, ++seedY;
da847a
      }
da847a
    }
da847a
  }
da847a
  
da847a
  
da847a
  void getModifiers(
da847a
    const TAffine &toTool,
da847a
    TInputModifier::List &outModifiers ) const override
da847a
  {
da847a
    double scale = getScale(toTool);
da847a
    outModifiers.push_back(new TModifierJitter(
da847a
      getPeriod()*scale,
da847a
      getAmplitude()*scale,
da847a
      getSkipFirst() ));
da847a
  }
da847a
da847a
  
da847a
  void draw(TToolViewer*, bool enabled) const override {
da847a
    double alpha = getDrawingAlpha(enabled);
da847a
    double pixelSize = sqrt(tglGetPixelSize2());
da847a
    
da847a
    TPointD c = m_center.position;
da847a
    double h = getPeriod()/2;
da847a
    double q = h/2;
da847a
    double a = getAmplitude();
da847a
    
da847a
    drawSegment(TPointD(c.x-h, c.y  ), TPointD(c.x-q, c.y+a), pixelSize, alpha);
da847a
    drawSegment(TPointD(c.x-q, c.y+a), TPointD(c.x+q, c.y-a), pixelSize, alpha);
da847a
    drawSegment(TPointD(c.x+q, c.y-a), TPointD(c.x+h, c.y  ), pixelSize, alpha);
da847a
  }
da847a
};
da847a
da847a
da847a
//*****************************************************************************************
da847a
//    Registration
da847a
//*****************************************************************************************
da847a
da847a
static TAssistantTypeT<treplicatorjitter> replicatorJitter("replicatorJitter");</treplicatorjitter>