Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tcamera.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// TCamera
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCamera::TCamera()
Shinya Kitaoka 120a6e
    //: m_size(12, 9), m_res(768, 576), m_xPrevalence(true)
shun_iwasawa d6df3f
    //: m_size(36, 20.25),
shun_iwasawa d6df3f
    : m_size(16, 9),
Shinya Kitaoka 120a6e
      m_res(1920, 1080),
Shinya Kitaoka 120a6e
      m_xPrevalence(true) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::setSize(const TDimensionD &size, bool preserveDpi,
Shinya Kitaoka 120a6e
                      bool preserveAR) {
Shinya Kitaoka 120a6e
  double currAR   = getAspectRatio();
Shinya Kitaoka 120a6e
  TPointD currDpi = getDpi();
Shinya Kitaoka 120a6e
  m_size.lx       = size.lx;
Shinya Kitaoka 120a6e
  if (preserveAR)
Shinya Kitaoka 120a6e
    m_size.ly = m_size.lx / currAR;  // WARNING! if also preserveDpi==true, the
Shinya Kitaoka 120a6e
                                     // AR could lose precision...
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_size.ly = size.ly;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!preserveDpi) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_res.lx  = troundp(currDpi.x * m_size.lx);
Shinya Kitaoka 120a6e
  m_res.ly  = troundp(currDpi.y * m_size.ly);
Shinya Kitaoka 120a6e
  m_size.lx = m_res.lx / currDpi.x;
Shinya Kitaoka 120a6e
  if (preserveAR)  //&& currDpi.x==currDpi.y)
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    double aux = m_size.lx / currAR - m_res.ly / currDpi.y;
Shinya Kitaoka 120a6e
    m_size.ly  = m_size.lx / currAR;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_size.ly = m_res.ly / currDpi.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TCamera::getAspectRatio() const { return m_size.lx / m_size.ly; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::setRes(const TDimension &res) {
Shinya Kitaoka 120a6e
  assert(res.lx > 0);
Shinya Kitaoka 120a6e
  assert(res.ly > 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_res != res) {
Shinya Kitaoka 120a6e
    m_res          = res;
Shinya Kitaoka 120a6e
    m_interestRect = TRect();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD TCamera::getDpi() const {
Shinya Kitaoka 120a6e
  TPointD dpi;
Shinya Kitaoka 120a6e
  if (m_size.lx > 0 && m_size.ly > 0) {
Shinya Kitaoka 120a6e
    dpi.x = m_res.lx / m_size.lx;
Shinya Kitaoka 120a6e
    dpi.y = m_res.ly / m_size.ly;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return dpi;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TCamera::isPixelSquared() const {
Shinya Kitaoka 120a6e
  return areAlmostEqual(m_res.lx * m_size.ly, m_res.ly * m_size.lx);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TCamera::getStageToCameraRef() const {
Shinya Kitaoka 120a6e
  return TAffine(m_res.lx / (Stage::inch * m_size.lx), 0, 0.5 * m_res.lx, 0,
Shinya Kitaoka 120a6e
                 m_res.ly / (Stage::inch * m_size.ly), 0.5 * m_res.ly);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TCamera::getCameraToStageRef() const {
Shinya Kitaoka 120a6e
  const double factor = Stage::inch;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TDimensionD cameraSize = getSize();
Shinya Kitaoka 120a6e
  cameraSize.lx *= factor;
Shinya Kitaoka 120a6e
  cameraSize.ly *= factor;
Shinya Kitaoka 120a6e
  TPointD center(0.5 * cameraSize.lx, 0.5 * cameraSize.ly);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return TAffine(factor * m_size.lx / (double)m_res.lx, 0, -center.x, 0,
Shinya Kitaoka 120a6e
                 factor * m_size.ly / (double)m_res.ly, -center.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD TCamera::getStageRect() const {
Shinya Kitaoka 120a6e
  TDimensionD cameraSize = getSize();
Shinya Kitaoka 120a6e
  const double factor    = Stage::inch;
Shinya Kitaoka 120a6e
  cameraSize.lx *= factor;
Shinya Kitaoka 120a6e
  cameraSize.ly *= factor;
Shinya Kitaoka 120a6e
  TRectD rect(cameraSize);
Shinya Kitaoka 120a6e
  rect -= 0.5 * (rect.getP00() + rect.getP11());
Shinya Kitaoka 120a6e
  return rect;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::setInterestRect(const TRect &rect) {
Shinya Kitaoka 120a6e
  // Not using the TRect's common intersection. Unfortunately, in case
Shinya Kitaoka 120a6e
  // the rect's coordinates have lx or ly < 0, the intersection returns
Shinya Kitaoka 120a6e
  // the default (empty) rect. We want to maintain the coordinates instead.
Shinya Kitaoka 120a6e
  // m_interestRect = rect * TRect(m_res);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_interestRect.x0 = std::max(rect.x0, 0);
Shinya Kitaoka 120a6e
  m_interestRect.y0 = std::max(rect.y0, 0);
Shinya Kitaoka 120a6e
  m_interestRect.x1 = std::min(rect.x1, m_res.lx - 1);
Shinya Kitaoka 120a6e
  m_interestRect.y1 = std::min(rect.y1, m_res.ly - 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD TCamera::getInterestStageRect() const {
Shinya Kitaoka 120a6e
  return getCameraToStageRef() * TRectD(m_interestRect.x0, m_interestRect.y0,
Shinya Kitaoka 120a6e
                                        m_interestRect.x1 + 1,
Shinya Kitaoka 120a6e
                                        m_interestRect.y1 + 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::setInterestStageRect(const TRectD &rect) {
Shinya Kitaoka 120a6e
  TRectD cameraInterestRectD(getStageToCameraRef() * rect);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  setInterestRect(TRect(
Shinya Kitaoka 120a6e
      tfloor(cameraInterestRectD.x0), tfloor(cameraInterestRectD.y0),
Shinya Kitaoka 120a6e
      tceil(cameraInterestRectD.x1) - 1, tceil(cameraInterestRectD.y1) - 1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::saveData(TOStream &os) const {
Shinya Kitaoka 120a6e
  os.child("cameraSize") << m_size.lx << m_size.ly;
Shinya Kitaoka 120a6e
  os.child("cameraRes") << m_res.lx << m_res.ly;
Shinya Kitaoka 120a6e
  os.child("cameraXPrevalence") << (int)m_xPrevalence;
Shinya Kitaoka 120a6e
  os.child("interestRect") << m_interestRect.x0 << m_interestRect.y0
Shinya Kitaoka 120a6e
                           << m_interestRect.x1 << m_interestRect.y1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TCamera::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "cameraSize" || tagName == "size")
Shinya Kitaoka 120a6e
      is >> m_size.lx >> m_size.ly;
Shinya Kitaoka 120a6e
    else if (tagName == "cameraRes" || tagName == "res")
Shinya Kitaoka 120a6e
      is >> m_res.lx >> m_res.ly;
Shinya Kitaoka 120a6e
    else if (tagName == "cameraXPrevalence") {
Shinya Kitaoka 120a6e
      int xPrevalence;
Shinya Kitaoka 120a6e
      is >> xPrevalence;
Shinya Kitaoka 120a6e
      m_xPrevalence = (bool)xPrevalence;
Shinya Kitaoka 120a6e
    } else if (tagName == "interestRect") {
Shinya Kitaoka 120a6e
      is >> m_interestRect.x0 >> m_interestRect.y0 >> m_interestRect.x1 >>
Shinya Kitaoka 120a6e
          m_interestRect.y1;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw TException("TCamera::loadData. unexpected tag: " + tagName);
Shinya Kitaoka 120a6e
    is.matchEndTag();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}