<commit_before>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./forces/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> labeller)

  : nodes(nodes), labels(labels), labeller(labeller), frustumOptimizer(nodes)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<Graphics::FrameBufferObject>(
      new Graphics::FrameBufferObject());
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  qDebug() << "Destructor of Scene";
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");

  fbo->initialize(gl, width, height);
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);
  Graphics::VolumeManager::instance->initialize(gl);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  frustumOptimizer.update(camera.getViewMatrix());
  camera.updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  auto newPositions = labeller->update(Forces::LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  // doPick();

  fbo->unbind();

  renderScreenQuad();
}

void Scene::renderScreenQuad()
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix =
      Eigen::Affine3f(Eigen::AlignedScaling3f(1, -1, 1)).matrix();

  fbo->bindColorTexture(GL_TEXTURE0);
  // fbo->bindDepthTexture(GL_TEXTURE0);

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  pickingPosition = position;
  performPicking = true;
  pickingLabelId = id;
}

void Scene::doPick()
{
  if (!performPicking)
    return;

  float depth = -2.0f;

  fbo->bindDepthTexture(GL_TEXTURE0);

  glAssert(gl->glReadPixels(pickingPosition.x(),
                            height - pickingPosition.y() - 1, 1, 1,
                            GL_DEPTH_COMPONENT, GL_FLOAT, &depth));
  Eigen::Vector4f positionNDC(pickingPosition.x() * 2.0f / width - 1.0f,
                              pickingPosition.y() * -2.0f / height + 1.0f,
                              depth * 2.0f - 1.0f, 1.0f);

  Eigen::Matrix4f viewProjection =
      camera.getProjectionMatrix() * camera.getViewMatrix();
  Eigen::Vector4f positionWorld = viewProjection.inverse() * positionNDC;
  positionWorld = positionWorld / positionWorld.w();

  qWarning() << "picked:" << positionWorld;

  performPicking = false;
  auto label = labels->getById(pickingLabelId);
  label.anchorPosition = toVector3f(positionWorld);

  labels->update(label);
}

<commit_msg>Clear nodes in Scene destructor.<commit_after>#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./camera_controller.h"
#include "./camera_rotation_controller.h"
#include "./camera_zoom_controller.h"
#include "./camera_move_controller.h"
#include "./nodes.h"
#include "./forces/labeller_frame_data.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"

Scene::Scene(std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<Forces::Labeller> labeller)

  : nodes(nodes), labels(labels), labeller(labeller), frustumOptimizer(nodes)
{
  cameraController = std::make_shared<CameraController>(camera);
  cameraRotationController = std::make_shared<CameraRotationController>(camera);
  cameraZoomController = std::make_shared<CameraZoomController>(camera);
  cameraMoveController = std::make_shared<CameraMoveController>(camera);

  invokeManager->addHandler("cam", cameraController.get());
  invokeManager->addHandler("cameraRotation", cameraRotationController.get());
  invokeManager->addHandler("cameraZoom", cameraZoomController.get());
  invokeManager->addHandler("cameraMove", cameraMoveController.get());

  fbo = std::unique_ptr<Graphics::FrameBufferObject>(
      new Graphics::FrameBufferObject());
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clear();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  glAssert(gl->glClearColor(0.9f, 0.9f, 0.8f, 1.0f));

  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");

  fbo->initialize(gl, width, height);
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);
  Graphics::VolumeManager::instance->initialize(gl);

  managers->getObjectManager()->initialize(gl, 128, 10000000);
  haBuffer->initialize(gl, managers);
  quad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);
}

void Scene::update(double frameTime, QSet<Qt::Key> keysPressed)
{
  this->frameTime = frameTime;
  cameraController->setFrameTime(frameTime);
  cameraRotationController->setFrameTime(frameTime);
  cameraZoomController->setFrameTime(frameTime);
  cameraMoveController->setFrameTime(frameTime);

  frustumOptimizer.update(camera.getViewMatrix());
  camera.updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                frustumOptimizer.getFar());
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  auto newPositions = labeller->update(Forces::LabellerFrameData(
      frameTime, camera.getProjectionMatrix(), camera.getViewMatrix()));

  for (auto &labelNode : nodes->getLabelNodes())
  {
    labelNode->labelPosition = newPositions[labelNode->label.id];
  }
}

void Scene::render()
{
  if (shouldResize)
  {
    camera.resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  RenderData renderData;
  renderData.projectionMatrix = camera.getProjectionMatrix();
  renderData.viewMatrix = camera.getViewMatrix();
  renderData.cameraPosition = camera.getPosition();
  renderData.modelMatrix = Eigen::Matrix4f::Identity();

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  haBuffer->render(managers, renderData);

  // doPick();

  fbo->unbind();

  renderScreenQuad();
}

void Scene::renderScreenQuad()
{
  RenderData renderData;
  renderData.projectionMatrix = Eigen::Matrix4f::Identity();
  renderData.viewMatrix = Eigen::Matrix4f::Identity();
  renderData.modelMatrix =
      Eigen::Affine3f(Eigen::AlignedScaling3f(1, -1, 1)).matrix();

  fbo->bindColorTexture(GL_TEXTURE0);
  // fbo->bindDepthTexture(GL_TEXTURE0);

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  pickingPosition = position;
  performPicking = true;
  pickingLabelId = id;
}

void Scene::doPick()
{
  if (!performPicking)
    return;

  float depth = -2.0f;

  fbo->bindDepthTexture(GL_TEXTURE0);

  glAssert(gl->glReadPixels(pickingPosition.x(),
                            height - pickingPosition.y() - 1, 1, 1,
                            GL_DEPTH_COMPONENT, GL_FLOAT, &depth));
  Eigen::Vector4f positionNDC(pickingPosition.x() * 2.0f / width - 1.0f,
                              pickingPosition.y() * -2.0f / height + 1.0f,
                              depth * 2.0f - 1.0f, 1.0f);

  Eigen::Matrix4f viewProjection =
      camera.getProjectionMatrix() * camera.getViewMatrix();
  Eigen::Vector4f positionWorld = viewProjection.inverse() * positionNDC;
  positionWorld = positionWorld / positionWorld.w();

  qWarning() << "picked:" << positionWorld;

  performPicking = false;
  auto label = labels->getById(pickingLabelId);
  label.anchorPosition = toVector3f(positionWorld);

  labels->update(label);
}

<|endoftext|>


<commit_before>#if _WIN32
#pragma warning(disable : 4522 4996 4267)
#endif

#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include <map>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/distance_transform.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./labelling_coordinator.h"
#include "./recording_automation.h"

Scene::Scene(int layerCount, std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<LabellingCoordinator> labellingCoordinator,
             std::shared_ptr<TextureMapperManager> textureMapperManager,
             std::shared_ptr<RecordingAutomation> recordingAutomation)

  : nodes(nodes), labels(labels), labellingCoordinator(labellingCoordinator),
    frustumOptimizer(nodes), textureMapperManager(textureMapperManager),
    recordingAutomation(recordingAutomation)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>(layerCount);
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clearForShutdown();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");
  sliceQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureSlice.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels, nodes);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 512, 10000000);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);
  sliceQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  haBuffer->initialize(gl, managers);

  textureMapperManager->createTextureMappersForLayers(fbo->getLayerCount());
  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  labellingCoordinator->initialize(gl, textureMapperManager->getBufferSize(),
                                   managers, textureMapperManager, width,
                                   height);

  recordingAutomation->initialize(gl);
  recordingAutomation->resize(width, height);
}

void Scene::cleanup()
{
  labellingCoordinator->cleanup();

  textureMapperManager->cleanup();
}

void Scene::update(double frameTime)
{
  auto camera = getCamera();

  if (camera->needsResizing())
    camera->resize(width, height);

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  camera->updateAnimation(frameTime);
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  RenderData newRenderData = createRenderData();
  bool isIdle =
      newRenderData.viewProjectionMatrix == renderData.viewProjectionMatrix;
  renderData = newRenderData;

  labellingCoordinator->update(frameTime, isIdle, camera->getProjectionMatrix(),
                               camera->getViewMatrix(), activeLayerNumber);
}

void Scene::render()
{
  qInfo() << "Scene::render";
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  renderNodesWithHABufferIntoFBO();

  textureMapperManager->update();

  constraintBufferObject->bind();

  labellingCoordinator->updatePlacement();

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (labellingEnabled)
  {
    fbo->bind();
    glAssert(gl->glDisable(GL_DEPTH_TEST));
    glAssert(gl->glEnable(GL_STENCIL_TEST));
    nodes->renderLabels(gl, managers, renderData);
    glAssert(gl->glDisable(GL_STENCIL_TEST));
    fbo->unbind();
  }

  renderScreenQuad();
  nodes->renderOverlays(gl, managers, renderData);

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  recordingAutomation->update();
}

void Scene::renderNodesWithHABufferIntoFBO()
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
                       GL_STENCIL_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  std::vector<float> zValues = labellingCoordinator->updateClusters();

  haBuffer->setLayerZValues(zValues, fbo->getLayerCount());
  haBuffer->render(managers, renderData);

  picker->doPick(renderData.viewProjectionMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  fbo->bindColorTexture(GL_TEXTURE0);
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8f + 0.4f * i, -0.4f, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
    renderSliceIntoQuad(transformation.matrix(), i);
  }

  fbo->bindAccumulatedLayersTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(
                          -0.8f + 0.4f * fbo->getLayerCount(), -0.4f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  fbo->bindDepthTexture(GL_TEXTURE0);
  transformation = Eigen::Affine3f(
      Eigen::Translation3f(Eigen::Vector3f(-0.8f, -0.8f, 0.0f)) *
      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOcclusionTexture();
  transformation = Eigen::Affine3f(
      Eigen::Translation3f(Eigen::Vector3f(-0.4f, -0.8f, 0.0f)) *
      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindSaliencyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  int layerIndex = activeLayerNumber == 0 ? 0 : activeLayerNumber - 1;
  if (layerIndex < fbo->getLayerCount())
    textureMapperManager->bindApollonius(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderSliceIntoQuad(Eigen::Matrix4f modelMatrix, int slice)
{
  RenderData renderData;
  renderData.modelMatrix = modelMatrix;

  sliceQuad->getShaderProgram()->bind();
  sliceQuad->getShaderProgram()->setUniform("textureSampler", 0);
  sliceQuad->getShaderProgram()->setUniform("slice", slice);
  sliceQuad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(GL_TEXTURE0);

    screenQuad->getShaderProgram()->setUniform("layers", 0);
    /*
    screenQuad->getShaderProgram()->setUniform("layer2", 1);
    screenQuad->getShaderProgram()->setUniform("layer3", 2);
    screenQuad->getShaderProgram()->setUniform("layer4", 3);
    */
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else if (activeLayerNumber == 9)
  {
    fbo->bindAccumulatedLayersTexture(GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
  else
  {
    fbo->bindColorTexture(GL_TEXTURE0);
    renderSliceIntoQuad(Eigen::Matrix4f::Identity(), activeLayerNumber - 1);
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;

  labellingCoordinator->resize(width, height);
  recordingAutomation->resize(width, height);
}

RenderData Scene::createRenderData()
{
  auto camera = getCamera();

  return RenderData(frameTime, camera->getProjectionMatrix(),
                    camera->getViewMatrix(), camera->getPosition(),
                    Eigen::Vector2f(width, height));
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

void Scene::enableLabelling(bool enable)
{
  labellingEnabled = enable;
  labellingCoordinator->setEnabled(enable);
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<commit_msg>Minor: remove commented out code.<commit_after>#if _WIN32
#pragma warning(disable : 4522 4996 4267)
#endif

#include "./scene.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <string>
#include <vector>
#include <map>
#include "./graphics/gl.h"
#include "./input/invoke_manager.h"
#include "./graphics/render_data.h"
#include "./graphics/managers.h"
#include "./graphics/volume_manager.h"
#include "./graphics/shader_program.h"
#include "./graphics/buffer_drawer.h"
#include "./camera_controllers.h"
#include "./nodes.h"
#include "./camera_node.h"
#include "./label_node.h"
#include "./eigen_qdebug.h"
#include "./utils/path_helper.h"
#include "./placement/distance_transform.h"
#include "./placement/apollonius.h"
#include "./texture_mapper_manager.h"
#include "./constraint_buffer_object.h"
#include "./labelling_coordinator.h"
#include "./recording_automation.h"

Scene::Scene(int layerCount, std::shared_ptr<InvokeManager> invokeManager,
             std::shared_ptr<Nodes> nodes, std::shared_ptr<Labels> labels,
             std::shared_ptr<LabellingCoordinator> labellingCoordinator,
             std::shared_ptr<TextureMapperManager> textureMapperManager,
             std::shared_ptr<RecordingAutomation> recordingAutomation)

  : nodes(nodes), labels(labels), labellingCoordinator(labellingCoordinator),
    frustumOptimizer(nodes), textureMapperManager(textureMapperManager),
    recordingAutomation(recordingAutomation)
{
  cameraControllers =
      std::make_shared<CameraControllers>(invokeManager, getCamera());

  fbo = std::make_shared<Graphics::FrameBufferObject>(layerCount);
  constraintBufferObject = std::make_shared<ConstraintBufferObject>();
  managers = std::make_shared<Graphics::Managers>();
}

Scene::~Scene()
{
  nodes->clearForShutdown();
  qInfo() << "Destructor of Scene"
          << "Remaining managers instances" << managers.use_count();
}

void Scene::initialize()
{
  quad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureForRenderBuffer.frag");
  screenQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/combineLayers.frag");
  positionQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/positionRenderTarget.frag");
  distanceTransformQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/distanceTransform.frag");
  transparentQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/transparentOverlay.frag");
  sliceQuad = std::make_shared<Graphics::ScreenQuad>(
      ":shader/pass.vert", ":shader/textureSlice.frag");

  fbo->initialize(gl, width, height);
  picker = std::make_unique<Picker>(fbo, gl, labels, nodes);
  picker->resize(width, height);
  constraintBufferObject->initialize(gl, textureMapperManager->getBufferSize(),
                                     textureMapperManager->getBufferSize());
  haBuffer =
      std::make_shared<Graphics::HABuffer>(Eigen::Vector2i(width, height));
  managers->getShaderManager()->initialize(gl, haBuffer);

  managers->getObjectManager()->initialize(gl, 512, 10000000);
  quad->initialize(gl, managers);
  screenQuad->initialize(gl, managers);
  positionQuad->initialize(gl, managers);
  distanceTransformQuad->initialize(gl, managers);
  transparentQuad->initialize(gl, managers);
  sliceQuad->initialize(gl, managers);

  managers->getTextureManager()->initialize(gl, true, 8);

  haBuffer->initialize(gl, managers);

  textureMapperManager->createTextureMappersForLayers(fbo->getLayerCount());
  textureMapperManager->resize(width, height);
  textureMapperManager->initialize(gl, fbo, constraintBufferObject);

  labellingCoordinator->initialize(gl, textureMapperManager->getBufferSize(),
                                   managers, textureMapperManager, width,
                                   height);

  recordingAutomation->initialize(gl);
  recordingAutomation->resize(width, height);
}

void Scene::cleanup()
{
  labellingCoordinator->cleanup();

  textureMapperManager->cleanup();
}

void Scene::update(double frameTime)
{
  auto camera = getCamera();

  if (camera->needsResizing())
    camera->resize(width, height);

  this->frameTime = frameTime;
  cameraControllers->update(camera, frameTime);

  frustumOptimizer.update(camera->getViewMatrix());
  camera->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                 frustumOptimizer.getFar());
  camera->updateAnimation(frameTime);
  haBuffer->updateNearAndFarPlanes(frustumOptimizer.getNear(),
                                   frustumOptimizer.getFar());

  RenderData newRenderData = createRenderData();
  bool isIdle =
      newRenderData.viewProjectionMatrix == renderData.viewProjectionMatrix;
  renderData = newRenderData;

  labellingCoordinator->update(frameTime, isIdle, camera->getProjectionMatrix(),
                               camera->getViewMatrix(), activeLayerNumber);
}

void Scene::render()
{
  qInfo() << "Scene::render";
  auto camera = getCamera();

  if (shouldResize)
  {
    camera->resize(width, height);
    fbo->resize(width, height);
    shouldResize = false;
  }

  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));

  renderNodesWithHABufferIntoFBO();

  textureMapperManager->update();

  constraintBufferObject->bind();

  labellingCoordinator->updatePlacement();

  constraintBufferObject->unbind();

  glAssert(gl->glViewport(0, 0, width, height));

  if (labellingEnabled)
  {
    fbo->bind();
    glAssert(gl->glDisable(GL_DEPTH_TEST));
    glAssert(gl->glEnable(GL_STENCIL_TEST));
    nodes->renderLabels(gl, managers, renderData);
    glAssert(gl->glDisable(GL_STENCIL_TEST));
    fbo->unbind();
  }

  renderScreenQuad();
  nodes->renderOverlays(gl, managers, renderData);

  if (showConstraintOverlay)
  {
    constraintBufferObject->bindTexture(GL_TEXTURE0);
    renderQuad(transparentQuad, Eigen::Matrix4f::Identity());
  }

  if (showBufferDebuggingViews)
    renderDebuggingViews(renderData);

  glAssert(gl->glEnable(GL_DEPTH_TEST));

  recordingAutomation->update();
}

void Scene::renderNodesWithHABufferIntoFBO()
{
  fbo->bind();
  glAssert(gl->glViewport(0, 0, width, height));
  glAssert(gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
                       GL_STENCIL_BUFFER_BIT));

  haBuffer->clearAndPrepare(managers);

  nodes->render(gl, managers, renderData);

  managers->getObjectManager()->render(renderData);

  std::vector<float> zValues = labellingCoordinator->updateClusters();

  haBuffer->setLayerZValues(zValues, fbo->getLayerCount());
  haBuffer->render(managers, renderData);

  picker->doPick(renderData.viewProjectionMatrix);

  fbo->unbind();
}

void Scene::renderDebuggingViews(const RenderData &renderData)
{
  fbo->bindColorTexture(GL_TEXTURE0);
  for (int i = 0; i < fbo->getLayerCount(); ++i)
  {
    auto transformation = Eigen::Affine3f(
        Eigen::Translation3f(Eigen::Vector3f(-0.8f + 0.4f * i, -0.4f, 0)) *
        Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
    renderSliceIntoQuad(transformation.matrix(), i);
  }

  fbo->bindAccumulatedLayersTexture(GL_TEXTURE0);
  auto transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(
                          -0.8f + 0.4f * fbo->getLayerCount(), -0.4f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  fbo->bindDepthTexture(GL_TEXTURE0);
  transformation = Eigen::Affine3f(
      Eigen::Translation3f(Eigen::Vector3f(-0.8f, -0.8f, 0.0f)) *
      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindOcclusionTexture();
  transformation = Eigen::Affine3f(
      Eigen::Translation3f(Eigen::Vector3f(-0.4f, -0.8f, 0.0f)) *
      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  textureMapperManager->bindSaliencyTexture();
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.0f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(distanceTransformQuad, transformation.matrix());

  int layerIndex = activeLayerNumber == 0 ? 0 : activeLayerNumber - 1;
  if (layerIndex < fbo->getLayerCount())
    textureMapperManager->bindApollonius(layerIndex);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.4f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());

  constraintBufferObject->bindTexture(GL_TEXTURE0);
  transformation =
      Eigen::Affine3f(Eigen::Translation3f(Eigen::Vector3f(0.8f, -0.8f, 0.0f)) *
                      Eigen::Scaling(Eigen::Vector3f(0.2f, 0.2f, 1.0f)));
  renderQuad(quad, transformation.matrix());
}

void Scene::renderQuad(std::shared_ptr<Graphics::ScreenQuad> quad,
                       Eigen::Matrix4f modelMatrix)
{
  RenderData renderData;
  renderData.modelMatrix = modelMatrix;

  quad->getShaderProgram()->bind();
  quad->getShaderProgram()->setUniform("textureSampler", 0);
  quad->renderImmediately(gl, managers, renderData);
}

void Scene::renderSliceIntoQuad(Eigen::Matrix4f modelMatrix, int slice)
{
  RenderData renderData;
  renderData.modelMatrix = modelMatrix;

  sliceQuad->getShaderProgram()->bind();
  sliceQuad->getShaderProgram()->setUniform("textureSampler", 0);
  sliceQuad->getShaderProgram()->setUniform("slice", slice);
  sliceQuad->renderImmediately(gl, managers, renderData);
}

void Scene::renderScreenQuad()
{
  if (activeLayerNumber == 0)
  {
    fbo->bindColorTexture(GL_TEXTURE0);

    screenQuad->getShaderProgram()->setUniform("layers", 0);
    renderQuad(screenQuad, Eigen::Matrix4f::Identity());

    gl->glActiveTexture(GL_TEXTURE0);
  }
  else if (activeLayerNumber == 9)
  {
    fbo->bindAccumulatedLayersTexture(GL_TEXTURE0);
    renderQuad(quad, Eigen::Matrix4f::Identity());
  }
  else
  {
    fbo->bindColorTexture(GL_TEXTURE0);
    renderSliceIntoQuad(Eigen::Matrix4f::Identity(), activeLayerNumber - 1);
  }
}

void Scene::resize(int width, int height)
{
  this->width = width;
  this->height = height;

  shouldResize = true;

  labellingCoordinator->resize(width, height);
  recordingAutomation->resize(width, height);
}

RenderData Scene::createRenderData()
{
  auto camera = getCamera();

  return RenderData(frameTime, camera->getProjectionMatrix(),
                    camera->getViewMatrix(), camera->getPosition(),
                    Eigen::Vector2f(width, height));
}

void Scene::pick(int id, Eigen::Vector2f position)
{
  if (picker.get())
    picker->pick(id, position);
}

void Scene::enableBufferDebuggingViews(bool enable)
{
  showBufferDebuggingViews = enable;
}

void Scene::enableConstraingOverlay(bool enable)
{
  showConstraintOverlay = enable;
}

void Scene::enableLabelling(bool enable)
{
  labellingEnabled = enable;
  labellingCoordinator->setEnabled(enable);
}

std::shared_ptr<Camera> Scene::getCamera()
{
  return nodes->getCameraNode()->getCamera();
}

void Scene::setRenderLayer(int layerNumber)
{
  activeLayerNumber = layerNumber;
}

<|endoftext|>


<commit_before>#include "defs.h"
#include "search.h"
#include "eval.h"
#include "movegen.h"
#include "transptable.h"
#include <string>
#include <ostream>
#include <time.h>
#include <iostream>

Search::Search(const Board& board, int depth, int maxTime, bool logUci) {
  _logUci = logUci;
  _iterDeep(board, depth, maxTime);
}

void Search::_iterDeep(const Board& board, int depth, int maxTime) {
  _tt.clear();

  int timeRemaining = maxTime;
  clock_t startTime;
  for(int i=1;i<=depth;i++) {
    startTime = clock();

    _rootMax(board, i);

    clock_t timeTaken = clock() - startTime;
    timeRemaining -= (float(timeTaken) / CLOCKS_PER_SEC)*1000;
    getPv(board);

    // Log UCI info about this iteration
    if (_logUci) {
      std::string pvString;
      for(auto move : getPv(board)) {
        pvString += move.getNotation() + " ";
      }
      std::cout << "info depth " + std::to_string(i) + " ";
      std::cout << "score cp " + std::to_string(_bestScore) + " ";
      std::cout << "pv " + pvString;
      std::cout << std::endl;
    }

    if (timeRemaining < 0) {
      return;
    }
  }
}

MoveList Search::getPv(const Board& board) {
  if (!_tt.contains(board.getZKey())) {
    return MoveList();
  }

  int scoreToFind = -_tt.getScore(board.getZKey());
  ZKey movedZKey;

  for (auto moveBoard : MoveGen(board).getLegalMoves()) {
    CMove move = moveBoard.first;
    Board movedBoard = moveBoard.second;

    movedZKey = movedBoard.getZKey();

    if (_tt.contains(movedZKey) && _tt.getScore(movedZKey) == scoreToFind) {
      MoveList pvList = getPv(movedBoard);
      pvList.insert(pvList.begin(), move);
      return pvList;
    }
  }

  return MoveList();
}

CMove Search::getBestMove() {
  return _bestMove;
}

void Search::_rootMax(const Board& board, int depth) {
  MoveGen movegen(board);
  MoveBoardList legalMoves = movegen.getLegalMoves();

  int bestScore = -INF;
  int currScore;
  CMove bestMove;
  for (auto moveBoard : legalMoves) {
    CMove move = moveBoard.first;
    Board movedBoard = moveBoard.second;

    currScore = -_negaMax(movedBoard, depth-1, -INF, INF);

    if (currScore > bestScore) {
      bestMove = move;
      bestScore = currScore;
    }
  }

  // If we couldn't find a path other than checkmate, just pick the first legal move
  if (bestMove.getFlags() & CMove::NULL_MOVE) {
    bestMove = legalMoves.at(0).first;
  }

  _tt.set(board.getZKey(), bestScore, depth, TranspTable::EXACT);

  _bestMove = bestMove;
  _bestScore = bestScore;
}

int Search::_negaMax(const Board& board, int depth, int alpha, int beta) {
  int alphaOrig = alpha;

  ZKey zKey = board.getZKey();
  // Check transposition table cache
  if (_tt.contains(zKey) && (_tt.getDepth(zKey) >= depth)) {
    switch(_tt.getFlag(zKey)) {
      case TranspTable::EXACT:
        return _tt.getScore(zKey);
      case TranspTable::UPPER_BOUND:
        alpha = std::max(alpha, _tt.getScore(zKey));
        break;
      case TranspTable::LOWER_BOUND:
        beta = std::min(beta, _tt.getScore(zKey));
        break;
    }

    if (alpha > beta) {
      return _tt.getScore(zKey);
    }
  }

  MoveGen movegen(board);
  MoveBoardList legalMoves = movegen.getLegalMoves();

  // Check for checkmate
  if (legalMoves.size() == 0 && board.colorIsInCheck(board.getActivePlayer())) {
    _tt.set(board.getZKey(), -INF, depth, TranspTable::EXACT);
    return -INF;
  }

  // Eval if depth is 0
  if (depth == 0) {
    int score = Eval(board, board.getActivePlayer()).getScore();
    _tt.set(board.getZKey(), score, 0, TranspTable::EXACT);
    return score;
  }

  int bestScore = -INF;
  for (auto moveBoard : legalMoves) {
    Board movedBoard = moveBoard.second;

    bestScore = std::max(bestScore, -_negaMax(movedBoard, depth-1, -beta, -alpha));

    alpha = std::max(alpha, bestScore);
    if (alpha > beta) {
      break;
    }
  }

  // Store bestScore in transposition table
  TranspTable::Flag flag;
  if (bestScore < alphaOrig) {
    flag = TranspTable::UPPER_BOUND;
  } else if (bestScore >= beta) {
    flag = TranspTable::LOWER_BOUND;
  } else {
    flag = TranspTable::EXACT;
  }
  _tt.set(zKey, bestScore, depth, flag);

  return bestScore;
}
<commit_msg>UCI log n moves to checkmate information<commit_after>#include "defs.h"
#include "search.h"
#include "eval.h"
#include "movegen.h"
#include "transptable.h"
#include <string>
#include <ostream>
#include <time.h>
#include <iostream>

Search::Search(const Board& board, int depth, int maxTime, bool logUci) {
  _logUci = logUci;
  _iterDeep(board, depth, maxTime);
}

void Search::_iterDeep(const Board& board, int depth, int maxTime) {
  _tt.clear();

  int timeRemaining = maxTime;
  clock_t startTime;
  for(int i=1;i<=depth;i++) {
    startTime = clock();

    _rootMax(board, i);

    clock_t timeTaken = clock() - startTime;
    timeRemaining -= (float(timeTaken) / CLOCKS_PER_SEC)*1000;

    // Log UCI info about this iteration
    if (_logUci) {
      std::string pvString;
      MoveList pv = getPv(board);
      for(auto move : pv) {
        pvString += move.getNotation() + " ";
      }

      std::string scoreString;
      if (_bestScore == INF) {
        scoreString = "mate " + std::to_string(pv.size());
      } else if (_bestScore == -INF) {
        scoreString = "mate -" + std::to_string(pv.size());
      } else {
        scoreString = "cp " + std::to_string(_bestScore);
      }

      std::cout << "info depth " + std::to_string(i) + " ";
      std::cout << "score " + scoreString + " ";
      std::cout << "pv " + pvString;
      std::cout << std::endl;
    }

    if (timeRemaining < 0) {
      return;
    }
  }
}

MoveList Search::getPv(const Board& board) {
  if (!_tt.contains(board.getZKey())) {
    return MoveList();
  }

  int scoreToFind = -_tt.getScore(board.getZKey());
  ZKey movedZKey;

  for (auto moveBoard : MoveGen(board).getLegalMoves()) {
    CMove move = moveBoard.first;
    Board movedBoard = moveBoard.second;

    movedZKey = movedBoard.getZKey();

    if (_tt.contains(movedZKey) && _tt.getScore(movedZKey) == scoreToFind) {
      MoveList pvList = getPv(movedBoard);
      pvList.insert(pvList.begin(), move);
      return pvList;
    }
  }

  return MoveList();
}

CMove Search::getBestMove() {
  return _bestMove;
}

void Search::_rootMax(const Board& board, int depth) {
  MoveGen movegen(board);
  MoveBoardList legalMoves = movegen.getLegalMoves();

  int bestScore = -INF;
  int currScore;
  CMove bestMove;
  for (auto moveBoard : legalMoves) {
    CMove move = moveBoard.first;
    Board movedBoard = moveBoard.second;

    currScore = -_negaMax(movedBoard, depth-1, -INF, INF);

    if (currScore > bestScore) {
      bestMove = move;
      bestScore = currScore;
    }
  }

  // If we couldn't find a path other than checkmate, just pick the first legal move
  if (bestMove.getFlags() & CMove::NULL_MOVE) {
    bestMove = legalMoves.at(0).first;
  }

  _tt.set(board.getZKey(), bestScore, depth, TranspTable::EXACT);

  _bestMove = bestMove;
  _bestScore = bestScore;
}

int Search::_negaMax(const Board& board, int depth, int alpha, int beta) {
  int alphaOrig = alpha;

  ZKey zKey = board.getZKey();
  // Check transposition table cache
  if (_tt.contains(zKey) && (_tt.getDepth(zKey) >= depth)) {
    switch(_tt.getFlag(zKey)) {
      case TranspTable::EXACT:
        return _tt.getScore(zKey);
      case TranspTable::UPPER_BOUND:
        alpha = std::max(alpha, _tt.getScore(zKey));
        break;
      case TranspTable::LOWER_BOUND:
        beta = std::min(beta, _tt.getScore(zKey));
        break;
    }

    if (alpha > beta) {
      return _tt.getScore(zKey);
    }
  }

  MoveGen movegen(board);
  MoveBoardList legalMoves = movegen.getLegalMoves();

  // Check for checkmate
  if (legalMoves.size() == 0 && board.colorIsInCheck(board.getActivePlayer())) {
    _tt.set(board.getZKey(), -INF, depth, TranspTable::EXACT);
    return -INF;
  }

  // Eval if depth is 0
  if (depth == 0) {
    int score = Eval(board, board.getActivePlayer()).getScore();
    _tt.set(board.getZKey(), score, 0, TranspTable::EXACT);
    return score;
  }

  int bestScore = -INF;
  for (auto moveBoard : legalMoves) {
    Board movedBoard = moveBoard.second;

    bestScore = std::max(bestScore, -_negaMax(movedBoard, depth-1, -beta, -alpha));

    alpha = std::max(alpha, bestScore);
    if (alpha > beta) {
      break;
    }
  }

  // Store bestScore in transposition table
  TranspTable::Flag flag;
  if (bestScore < alphaOrig) {
    flag = TranspTable::UPPER_BOUND;
  } else if (bestScore >= beta) {
    flag = TranspTable::LOWER_BOUND;
  } else {
    flag = TranspTable::EXACT;
  }
  _tt.set(zKey, bestScore, depth, flag);

  return bestScore;
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2016 The Dash developers
// Copyright (c) 2016-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "spork.h"

#include "messagesigner.h"
#include "net.h"
#include "netmessagemaker.h"
#include "net_processing.h"
#include "sporkdb.h"
#include "validation.h"

#include <iostream>

#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef(name, defaultValue, #name)

std::vector<CSporkDef> sporkDefs = {
    MAKE_SPORK_DEF(SPORK_5_MAX_VALUE,                       1000),          // 1000 PIV
    MAKE_SPORK_DEF(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT,  4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT,   4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_13_ENABLE_SUPERBLOCKS,             4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_14_NEW_PROTOCOL_ENFORCEMENT,       4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2,     4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_16_ZEROCOIN_MAINTENANCE_MODE,      4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_18_ZEROCOIN_PUBLICSPEND_V4,        4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_19_COLDSTAKING_MAINTENANCE,        4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_20_SAPLING_MAINTENANCE,            4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_21_LEGACY_MNS_MAX_HEIGHT,          4070908800ULL), // OFF
};

CSporkManager sporkManager;
std::map<uint256, CSporkMessage> mapSporks;

CSporkManager::CSporkManager()
{
    for (auto& sporkDef : sporkDefs) {
        sporkDefsById.emplace(sporkDef.sporkId, &sporkDef);
        sporkDefsByName.emplace(sporkDef.name, &sporkDef);
    }
}

void CSporkManager::Clear()
{
    strMasterPrivKey = "";
    mapSporksActive.clear();
}

// PIVX: on startup load spork values from previous session if they exist in the sporkDB
void CSporkManager::LoadSporksFromDB()
{
    for (const auto& sporkDef : sporkDefs) {
        // attempt to read spork from sporkDB
        CSporkMessage spork;
        if (!pSporkDB->ReadSpork(sporkDef.sporkId, spork)) {
            LogPrintf("%s : no previous value for %s found in database\n", __func__, sporkDef.name);
            continue;
        }

        // TODO: Temporary workaround for v5.0 clients to ensure up-to-date protocol version spork
        if (spork.nSporkID == SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2) {
            LogPrintf("%s : Spork 15 signed at %d\n", __func__, spork.nTimeSigned);
            // 1578338986 is the timestamp that spork 15 was last signed at for mainnet for the previous
            // protocol bump. If the timestamp in the DB is equal or lower than this, we know that
            // the value is stale and should ignore it to prevent un-necessary disconnections in the
            // version handshake process. This value is also suitable for testnet as the timestamp
            // for this spork on that network was signed shortly after this.
            if (spork.nTimeSigned <= 1578338986 ) {
                LogPrintf("%s : Stale spork 15 detected, clearing...\n", __func__);
                CSporkManager::Clear();
                return;
            }
        }

        // add spork to memory
        mapSporks[spork.GetHash()] = spork;
        mapSporksActive[spork.nSporkID] = spork;
        std::time_t result = spork.nValue;
        // If SPORK Value is greater than 1,000,000 assume it's actually a Date and then convert to a more readable format
        std::string sporkName = sporkManager.GetSporkNameByID(spork.nSporkID);
        if (spork.nValue > 1000000) {
            char* res = std::ctime(&result);
            LogPrintf("%s : loaded spork %s with value %d : %s\n", __func__, sporkName.c_str(), spork.nValue,
                      ((res) ? res : "no time") );
        } else {
            LogPrintf("%s : loaded spork %s with value %d\n", __func__,
                      sporkName, spork.nValue);
        }
    }
}

void CSporkManager::ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (fLiteMode) return; // disable all masternode related functionality

    if (strCommand == NetMsgType::SPORK) {
        int banScore = ProcessSporkMsg(vRecv);
        if (banScore > 0) {
            LOCK(cs_main);
            Misbehaving(pfrom->GetId(), banScore);
        }
    }
    if (strCommand == NetMsgType::GETSPORKS) {
        ProcessGetSporks(pfrom, strCommand, vRecv);
    }
}

int CSporkManager::ProcessSporkMsg(CDataStream& vRecv)
{
    CSporkMessage spork;
    vRecv >> spork;
    return ProcessSporkMsg(spork);
}

int CSporkManager::ProcessSporkMsg(CSporkMessage& spork)
{
    // Ignore spork messages about unknown/deleted sporks
    std::string strSpork = sporkManager.GetSporkNameByID(spork.nSporkID);
    if (strSpork == "Unknown") return 0;

    // Do not accept sporks signed way too far into the future
    if (spork.nTimeSigned > GetAdjustedTime() + 2 * 60 * 60) {
        LogPrint(BCLog::SPORKS, "%s : ERROR: too far into the future\n", __func__);
        return 100;
    }

    // reject old signature version
    if (spork.nMessVersion != MessageVersion::MESS_VER_HASH) {
        LogPrint(BCLog::SPORKS, "%s : nMessVersion=%d not accepted anymore\n", __func__, spork.nMessVersion);
        return 0;
    }

    uint256 hash = spork.GetHash();
    std::string sporkName = sporkManager.GetSporkNameByID(spork.nSporkID);
    std::string strStatus;
    {
        LOCK(cs);
        if (mapSporksActive.count(spork.nSporkID)) {
            // spork is active
            if (mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned) {
                // spork in memory has been signed more recently
                LogPrint(BCLog::SPORKS, "%s : spork %d (%s) in memory is more recent: %d >= %d\n", __func__,
                          spork.nSporkID, sporkName,
                          mapSporksActive[spork.nSporkID].nTimeSigned, spork.nTimeSigned);
                return 0;
            } else {
                // update active spork
                strStatus = "updated";
            }
        } else {
            // spork is not active
            strStatus = "new";
        }
    }

    const bool fRequireNew = spork.nTimeSigned >= Params().GetConsensus().nTime_EnforceNewSporkKey;
    bool fValidSig = spork.CheckSignature(spork.GetPublicKey().GetID());
    if (!fValidSig && !fRequireNew) {
        // See if window is open that allows for old spork key to sign messages
        if (GetAdjustedTime() < Params().GetConsensus().nTime_RejectOldSporkKey) {
            CPubKey pubkeyold = spork.GetPublicKeyOld();
            fValidSig = spork.CheckSignature(pubkeyold.GetID());
        }
    }

    if (!fValidSig) {
        LogPrint(BCLog::SPORKS, "%s : Invalid Signature\n", __func__);
        return 100;
    }

    // Log valid spork value change
    LogPrintf("%s : got %s spork %d (%s) with value %d (signed at %d)\n", __func__,
              strStatus, spork.nSporkID, sporkName, spork.nValue, spork.nTimeSigned);

    {
        LOCK(cs);
        mapSporks[hash] = spork;
        mapSporksActive[spork.nSporkID] = spork;
    }
    spork.Relay();

    // PIVX: add to spork database.
    pSporkDB->WriteSpork(spork.nSporkID, spork);
    // All good.
    return 0;
}

void CSporkManager::ProcessGetSporks(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    LOCK(cs);

    std::map<SporkId, CSporkMessage>::iterator it = mapSporksActive.begin();

    while (it != mapSporksActive.end()) {
        g_connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::SPORK, it->second));
        it++;
    }

    // end message
    if (Params().IsRegTestNet()) {
        // For now, only use it on regtest.
        CSporkMessage msg(SPORK_INVALID, 0, 0);
        g_connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::SPORK, msg));
    }
}

bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue)
{
    CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetTime());

    if(spork.Sign(strMasterPrivKey)){
        spork.Relay();
        AddSporkMessage(spork);
        return true;
    }

    return false;
}

void CSporkManager::AddSporkMessage(const CSporkMessage& spork)
{
    LOCK(cs);
    mapSporks[spork.GetHash()] = spork;
    mapSporksActive[spork.nSporkID] = spork;
}

// grab the spork value, and see if it's off
bool CSporkManager::IsSporkActive(SporkId nSporkID)
{
    return GetSporkValue(nSporkID) < GetAdjustedTime();
}

// grab the value of the spork on the network, or the default
int64_t CSporkManager::GetSporkValue(SporkId nSporkID)
{
    LOCK(cs);

    if (mapSporksActive.count(nSporkID)) {
        return mapSporksActive[nSporkID].nValue;

    } else {
        auto it = sporkDefsById.find(nSporkID);
        if (it != sporkDefsById.end()) {
            return it->second->defaultValue;
        } else {
            LogPrintf("%s : Unknown Spork %d\n", __func__, nSporkID);
        }
    }

    return -1;
}

SporkId CSporkManager::GetSporkIDByName(std::string strName)
{
    auto it = sporkDefsByName.find(strName);
    if (it == sporkDefsByName.end()) {
        LogPrintf("%s : Unknown Spork name '%s'\n", __func__, strName);
        return SPORK_INVALID;
    }
    return it->second->sporkId;
}

std::string CSporkManager::GetSporkNameByID(SporkId nSporkID)
{
    auto it = sporkDefsById.find(nSporkID);
    if (it == sporkDefsById.end()) {
        LogPrint(BCLog::SPORKS, "%s : Unknown Spork ID %d\n", __func__, nSporkID);
        return "Unknown";
    }
    return it->second->name;
}

bool CSporkManager::SetPrivKey(std::string strPrivKey)
{
    CSporkMessage spork;

    spork.Sign(strPrivKey);

    bool fValidSig = spork.CheckSignature(spork.GetPublicKey().GetID());
    if (!fValidSig) {
        // See if window is open that allows for old spork key to sign messages
        if (GetAdjustedTime() < Params().GetConsensus().nTime_RejectOldSporkKey) {
            CPubKey pubkeyold = spork.GetPublicKeyOld();
            fValidSig = spork.CheckSignature(pubkeyold.GetID());
        }
    }
    if (fValidSig) {
        LOCK(cs);
        // Test signing successful, proceed
        LogPrintf("%s : Successfully initialized as spork signer\n", __func__);
        strMasterPrivKey = strPrivKey;
        return true;
    }

    return false;
}

std::string CSporkManager::ToString() const
{
    LOCK(cs);
    return strprintf("Sporks: %llu", mapSporksActive.size());
}

uint256 CSporkMessage::GetSignatureHash() const
{
    CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
    ss << nMessVersion;
    ss << nSporkID;
    ss << nValue;
    ss << nTimeSigned;
    return ss.GetHash();
}

std::string CSporkMessage::GetStrMessage() const
{
    return std::to_string(nSporkID) +
            std::to_string(nValue) +
            std::to_string(nTimeSigned);
}

const CPubKey CSporkMessage::GetPublicKey() const
{
    return CPubKey(ParseHex(Params().GetConsensus().strSporkPubKey));
}

const CPubKey CSporkMessage::GetPublicKeyOld() const
{
    return CPubKey(ParseHex(Params().GetConsensus().strSporkPubKeyOld));
}

void CSporkMessage::Relay()
{
    CInv inv(MSG_SPORK, GetHash());
    g_connman->RelayInv(inv);
}

<commit_msg>[Refactoring] Use AddSporkMessage globally for maps update<commit_after>// Copyright (c) 2014-2016 The Dash developers
// Copyright (c) 2016-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "spork.h"

#include "messagesigner.h"
#include "net.h"
#include "netmessagemaker.h"
#include "net_processing.h"
#include "sporkdb.h"
#include "validation.h"

#include <iostream>

#define MAKE_SPORK_DEF(name, defaultValue) CSporkDef(name, defaultValue, #name)

std::vector<CSporkDef> sporkDefs = {
    MAKE_SPORK_DEF(SPORK_5_MAX_VALUE,                       1000),          // 1000 PIV
    MAKE_SPORK_DEF(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT,  4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_9_MASTERNODE_BUDGET_ENFORCEMENT,   4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_13_ENABLE_SUPERBLOCKS,             4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_14_NEW_PROTOCOL_ENFORCEMENT,       4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2,     4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_16_ZEROCOIN_MAINTENANCE_MODE,      4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_18_ZEROCOIN_PUBLICSPEND_V4,        4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_19_COLDSTAKING_MAINTENANCE,        4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_20_SAPLING_MAINTENANCE,            4070908800ULL), // OFF
    MAKE_SPORK_DEF(SPORK_21_LEGACY_MNS_MAX_HEIGHT,          4070908800ULL), // OFF
};

CSporkManager sporkManager;
std::map<uint256, CSporkMessage> mapSporks;

CSporkManager::CSporkManager()
{
    for (auto& sporkDef : sporkDefs) {
        sporkDefsById.emplace(sporkDef.sporkId, &sporkDef);
        sporkDefsByName.emplace(sporkDef.name, &sporkDef);
    }
}

void CSporkManager::Clear()
{
    strMasterPrivKey = "";
    mapSporksActive.clear();
}

// PIVX: on startup load spork values from previous session if they exist in the sporkDB
void CSporkManager::LoadSporksFromDB()
{
    for (const auto& sporkDef : sporkDefs) {
        // attempt to read spork from sporkDB
        CSporkMessage spork;
        if (!pSporkDB->ReadSpork(sporkDef.sporkId, spork)) {
            LogPrintf("%s : no previous value for %s found in database\n", __func__, sporkDef.name);
            continue;
        }

        // TODO: Temporary workaround for v5.0 clients to ensure up-to-date protocol version spork
        if (spork.nSporkID == SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2) {
            LogPrintf("%s : Spork 15 signed at %d\n", __func__, spork.nTimeSigned);
            // 1578338986 is the timestamp that spork 15 was last signed at for mainnet for the previous
            // protocol bump. If the timestamp in the DB is equal or lower than this, we know that
            // the value is stale and should ignore it to prevent un-necessary disconnections in the
            // version handshake process. This value is also suitable for testnet as the timestamp
            // for this spork on that network was signed shortly after this.
            if (spork.nTimeSigned <= 1578338986 ) {
                LogPrintf("%s : Stale spork 15 detected, clearing...\n", __func__);
                CSporkManager::Clear();
                return;
            }
        }

        // add spork to memory
        AddSporkMessage(spork);
        mapSporks[spork.GetHash()] = spork;
        mapSporksActive[spork.nSporkID] = spork;
        std::time_t result = spork.nValue;
        // If SPORK Value is greater than 1,000,000 assume it's actually a Date and then convert to a more readable format
        std::string sporkName = sporkManager.GetSporkNameByID(spork.nSporkID);
        if (spork.nValue > 1000000) {
            char* res = std::ctime(&result);
            LogPrintf("%s : loaded spork %s with value %d : %s\n", __func__, sporkName.c_str(), spork.nValue,
                      ((res) ? res : "no time") );
        } else {
            LogPrintf("%s : loaded spork %s with value %d\n", __func__,
                      sporkName, spork.nValue);
        }
    }
}

void CSporkManager::ProcessSpork(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (fLiteMode) return; // disable all masternode related functionality

    if (strCommand == NetMsgType::SPORK) {
        int banScore = ProcessSporkMsg(vRecv);
        if (banScore > 0) {
            LOCK(cs_main);
            Misbehaving(pfrom->GetId(), banScore);
        }
    }
    if (strCommand == NetMsgType::GETSPORKS) {
        ProcessGetSporks(pfrom, strCommand, vRecv);
    }
}

int CSporkManager::ProcessSporkMsg(CDataStream& vRecv)
{
    CSporkMessage spork;
    vRecv >> spork;
    return ProcessSporkMsg(spork);
}

int CSporkManager::ProcessSporkMsg(CSporkMessage& spork)
{
    // Ignore spork messages about unknown/deleted sporks
    std::string strSpork = sporkManager.GetSporkNameByID(spork.nSporkID);
    if (strSpork == "Unknown") return 0;

    // Do not accept sporks signed way too far into the future
    if (spork.nTimeSigned > GetAdjustedTime() + 2 * 60 * 60) {
        LogPrint(BCLog::SPORKS, "%s : ERROR: too far into the future\n", __func__);
        return 100;
    }

    // reject old signature version
    if (spork.nMessVersion != MessageVersion::MESS_VER_HASH) {
        LogPrint(BCLog::SPORKS, "%s : nMessVersion=%d not accepted anymore\n", __func__, spork.nMessVersion);
        return 0;
    }

    std::string sporkName = sporkManager.GetSporkNameByID(spork.nSporkID);
    std::string strStatus;
    {
        LOCK(cs);
        if (mapSporksActive.count(spork.nSporkID)) {
            // spork is active
            if (mapSporksActive[spork.nSporkID].nTimeSigned >= spork.nTimeSigned) {
                // spork in memory has been signed more recently
                LogPrint(BCLog::SPORKS, "%s : spork %d (%s) in memory is more recent: %d >= %d\n", __func__,
                          spork.nSporkID, sporkName,
                          mapSporksActive[spork.nSporkID].nTimeSigned, spork.nTimeSigned);
                return 0;
            } else {
                // update active spork
                strStatus = "updated";
            }
        } else {
            // spork is not active
            strStatus = "new";
        }
    }

    const bool fRequireNew = spork.nTimeSigned >= Params().GetConsensus().nTime_EnforceNewSporkKey;
    bool fValidSig = spork.CheckSignature(spork.GetPublicKey().GetID());
    if (!fValidSig && !fRequireNew) {
        // See if window is open that allows for old spork key to sign messages
        if (GetAdjustedTime() < Params().GetConsensus().nTime_RejectOldSporkKey) {
            CPubKey pubkeyold = spork.GetPublicKeyOld();
            fValidSig = spork.CheckSignature(pubkeyold.GetID());
        }
    }

    if (!fValidSig) {
        LogPrint(BCLog::SPORKS, "%s : Invalid Signature\n", __func__);
        return 100;
    }

    // Log valid spork value change
    LogPrintf("%s : got %s spork %d (%s) with value %d (signed at %d)\n", __func__,
              strStatus, spork.nSporkID, sporkName, spork.nValue, spork.nTimeSigned);

    AddSporkMessage(spork);
    spork.Relay();

    // PIVX: add to spork database.
    pSporkDB->WriteSpork(spork.nSporkID, spork);
    // All good.
    return 0;
}

void CSporkManager::ProcessGetSporks(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    LOCK(cs);

    std::map<SporkId, CSporkMessage>::iterator it = mapSporksActive.begin();

    while (it != mapSporksActive.end()) {
        g_connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::SPORK, it->second));
        it++;
    }

    // end message
    if (Params().IsRegTestNet()) {
        // For now, only use it on regtest.
        CSporkMessage msg(SPORK_INVALID, 0, 0);
        g_connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::SPORK, msg));
    }
}

bool CSporkManager::UpdateSpork(SporkId nSporkID, int64_t nValue)
{
    CSporkMessage spork = CSporkMessage(nSporkID, nValue, GetTime());

    if(spork.Sign(strMasterPrivKey)){
        spork.Relay();
        AddSporkMessage(spork);
        return true;
    }

    return false;
}

void CSporkManager::AddSporkMessage(const CSporkMessage& spork)
{
    LOCK(cs);
    mapSporks[spork.GetHash()] = spork;
    mapSporksActive[spork.nSporkID] = spork;
}

// grab the spork value, and see if it's off
bool CSporkManager::IsSporkActive(SporkId nSporkID)
{
    return GetSporkValue(nSporkID) < GetAdjustedTime();
}

// grab the value of the spork on the network, or the default
int64_t CSporkManager::GetSporkValue(SporkId nSporkID)
{
    LOCK(cs);

    if (mapSporksActive.count(nSporkID)) {
        return mapSporksActive[nSporkID].nValue;

    } else {
        auto it = sporkDefsById.find(nSporkID);
        if (it != sporkDefsById.end()) {
            return it->second->defaultValue;
        } else {
            LogPrintf("%s : Unknown Spork %d\n", __func__, nSporkID);
        }
    }

    return -1;
}

SporkId CSporkManager::GetSporkIDByName(std::string strName)
{
    auto it = sporkDefsByName.find(strName);
    if (it == sporkDefsByName.end()) {
        LogPrintf("%s : Unknown Spork name '%s'\n", __func__, strName);
        return SPORK_INVALID;
    }
    return it->second->sporkId;
}

std::string CSporkManager::GetSporkNameByID(SporkId nSporkID)
{
    auto it = sporkDefsById.find(nSporkID);
    if (it == sporkDefsById.end()) {
        LogPrint(BCLog::SPORKS, "%s : Unknown Spork ID %d\n", __func__, nSporkID);
        return "Unknown";
    }
    return it->second->name;
}

bool CSporkManager::SetPrivKey(std::string strPrivKey)
{
    CSporkMessage spork;

    spork.Sign(strPrivKey);

    bool fValidSig = spork.CheckSignature(spork.GetPublicKey().GetID());
    if (!fValidSig) {
        // See if window is open that allows for old spork key to sign messages
        if (GetAdjustedTime() < Params().GetConsensus().nTime_RejectOldSporkKey) {
            CPubKey pubkeyold = spork.GetPublicKeyOld();
            fValidSig = spork.CheckSignature(pubkeyold.GetID());
        }
    }
    if (fValidSig) {
        LOCK(cs);
        // Test signing successful, proceed
        LogPrintf("%s : Successfully initialized as spork signer\n", __func__);
        strMasterPrivKey = strPrivKey;
        return true;
    }

    return false;
}

std::string CSporkManager::ToString() const
{
    LOCK(cs);
    return strprintf("Sporks: %llu", mapSporksActive.size());
}

uint256 CSporkMessage::GetSignatureHash() const
{
    CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
    ss << nMessVersion;
    ss << nSporkID;
    ss << nValue;
    ss << nTimeSigned;
    return ss.GetHash();
}

std::string CSporkMessage::GetStrMessage() const
{
    return std::to_string(nSporkID) +
            std::to_string(nValue) +
            std::to_string(nTimeSigned);
}

const CPubKey CSporkMessage::GetPublicKey() const
{
    return CPubKey(ParseHex(Params().GetConsensus().strSporkPubKey));
}

const CPubKey CSporkMessage::GetPublicKeyOld() const
{
    return CPubKey(ParseHex(Params().GetConsensus().strSporkPubKeyOld));
}

void CSporkMessage::Relay()
{
    CInv inv(MSG_SPORK, GetHash());
    g_connman->RelayInv(inv);
}

<|endoftext|>


<commit_before>#include "io.h"

/* Writes noise, fractal and water info to file_name */
void writeFile(string file_name, NoiseParams *noise_params, WaterParams *water_params) {
	/*ofstream myfile(file_name);

	if (myfile.is_open()) {

	/* Write header
	myfile << IO_HEADER_STRING << endl;

	/* The order is not important

	/* Noise
	myfile << "noise_type " << noise_params->type << endl;
	myfile << "noise_width " << noise_params->width << endl;
	myfile << "noise_height " << noise_params->height << endl;
	myfile << "noise_offset " << noise_params->offset << endl;
	myfile << "noise_amplitude " << noise_params->amplitude << endl;
	myfile << "noise_seed " << noise_params->seed << endl;

	/* Fractal
	if (fractal_params->enable) {
	myfile << "fractal_enable " << "true" << endl;
	myfile << "fractal_H " << fractal_params->H << endl;
	myfile << "fractal_lacunarity " << fractal_params->lacunarity << endl;
	myfile << "fractal_octaves " << fractal_params->octaves << endl;
	myfile << "fractal_offset " << fractal_params->offset << endl;
	myfile << "fractal_amplitude " << fractal_params->amplitude << endl;

	}
	else {
	myfile << "fractal_enable " << "false" << endl;
	}

	/* Water
	myfile << "water_height " << water_params->height << endl;
	myfile << "water_transparency " << water_params->transparency << endl;
	myfile << "water_depth_alpha_factor " << water_params->depth_alpha_factor << endl;
	myfile << "water_depth_color_factor " << water_params->depth_color_factor << endl;
	myfile << "water_color " << water_params->color[0] << ' ' << water_params->color[1] << ' ' << water_params->color[2] << endl;

	myfile.close();
	std::cout << "[Info] Data saved to " << file_name << endl;
	}
	else {
	std::cout << "[Error] Could not save data: the file " << file_name << " could not be opened." << endl;
	}*/
}

void loadFromFile(string file_name, NoiseParams *noise_params, WaterParams *water_params) {
	/*string line;
	ifstream myfile(file_name);
	if (myfile.is_open())
	{

	int line_no = 0;

	while (getline(myfile, line))
	{
	line_no++;

	if (line_no == 1) {
	if (line.compare(IO_HEADER_STRING)) {
	// the first line doesn't match the header -> illegal format
	std::cout << "Error: Illegal header. Aborting load." << endl;
	return;
	}
	}
	string str = line;

	// construct a stream from the string
	stringstream strstr(str);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	istream_iterator<string> it(strstr);
	istream_iterator<string> end;
	vector<string> results(it, end);

	/* Load fractal
	if (!results[0].compare("fractal_enable")) {
	if (!results[1].compare("true")) {
	fractal_params->enable = true;
	}
	else {
	}
	}
	else if (!results[0].compare("fractal_H")) {
	fractal_params->H = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("fractal_lacunarity")) {
	fractal_params->lacunarity = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("fractal_octaves")) {
	fractal_params->octaves = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("fractal_offset")) {
	fractal_params->offset = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("fractal_amplitude")) {
	fractal_params->amplitude = ::atof(results[1].c_str());
	}

	/* Load noise
	else if (!results[0].compare("noise_type")) {
	int type = ::atoi(results[1].c_str());
	switch (type) {
	case 0: noise_params->type = COPY_TEXTURE;
	break;
	case 1: noise_params->type = NO_NOISE;
	break;
	case 2: noise_params->type = RANDOM_NOISE;
	break;
	case 3: noise_params->type = PERLIN_NOISE;
	break;
	case 4: noise_params->type = PERLIN_NOISE_ABS;
	break;
	default:
	std::cout << "[Error] Unkown NoiseType" << endl;
	break;
	}

	}
	else if (!results[0].compare("noise_width")) {
	noise_params->width = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("noise_height")) {
	noise_params->height = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("noise_offset")) {
	noise_params->offset = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("noise_amplitude")) {
	noise_params->amplitude = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("noise_seed")) {
	noise_params->seed = ::atof(results[1].c_str());
	}

	/* Load water
	else if (!results[0].compare("water_height")) {
	water_params->height = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_transparency")) {
	water_params->transparency = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_depth_alpha_factor")) {
	water_params->depth_alpha_factor = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_depth_color_factor")) {
	water_params->depth_color_factor = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_color")) {
	water_params->color = vec3(::atof(results[1].c_str()), ::atof(results[2].c_str()), ::atof(results[3].c_str()));
	}
	}

	myfile.close();
	std::cout << "[Info] Data loaded from " << file_name << endl;
	}
	else {
	std::cout << "[Error] Could not load data: the file" << file_name << " could not be opened." << endl;
	}*/
}

bool save_screenshot(string filename, int w, int h)
{
	//This prevents the images getting padded
	// when the width multiplied by 3 is not a multiple of 4
	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	int nSize = w*h * 3;
	// First let's create our buffer, 3 channels per Pixel
	char* dataBuffer = (char*)malloc(nSize*sizeof(char));

	if (!dataBuffer) return false;

	// Let's fetch them from the backbuffer
	// We request the pixels in GL_BGR format, thanks to Berzeger for the tip
	glReadPixels((GLint)0, (GLint)0,
		(GLint)w, (GLint)h,
		GL_BGR, GL_UNSIGNED_BYTE, dataBuffer);

	//Now the file creation
	FILE *filePtr = fopen(filename.c_str(), "wb");
	if (!filePtr) return false;

	unsigned char TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned char header[6] = { w % 256, w / 256,
		h % 256, h / 256,
		24, 0 };
	// We write the headers
	fwrite(TGAheader, sizeof(unsigned char), 12, filePtr);
	fwrite(header, sizeof(unsigned char), 6, filePtr);
	// And finally our image data
	fwrite(dataBuffer, sizeof(GLubyte), nSize, filePtr);
	fclose(filePtr);

	return true;
}

string get_unique_name() {
	std::stringstream ss;

	time_t t = time(0);
	struct tm * now = localtime(&t);

	ss << (now->tm_year + 1900) << '-'
		<< (now->tm_mon + 1) << '-'
		<< now->tm_mday << '-'
		<< now->tm_hour << '-'
		<< now->tm_min << '-'
		<< now->tm_sec
		<< ".tga";

	return ss.str();
}<commit_msg>Free data buffer after screenshot<commit_after>#include "io.h"

/* Writes noise, fractal and water info to file_name */
void writeFile(string file_name, NoiseParams *noise_params, WaterParams *water_params) {
	/*ofstream myfile(file_name);

	if (myfile.is_open()) {

	/* Write header
	myfile << IO_HEADER_STRING << endl;

	/* The order is not important

	/* Noise
	myfile << "noise_type " << noise_params->type << endl;
	myfile << "noise_width " << noise_params->width << endl;
	myfile << "noise_height " << noise_params->height << endl;
	myfile << "noise_offset " << noise_params->offset << endl;
	myfile << "noise_amplitude " << noise_params->amplitude << endl;
	myfile << "noise_seed " << noise_params->seed << endl;

	/* Fractal
	if (fractal_params->enable) {
	myfile << "fractal_enable " << "true" << endl;
	myfile << "fractal_H " << fractal_params->H << endl;
	myfile << "fractal_lacunarity " << fractal_params->lacunarity << endl;
	myfile << "fractal_octaves " << fractal_params->octaves << endl;
	myfile << "fractal_offset " << fractal_params->offset << endl;
	myfile << "fractal_amplitude " << fractal_params->amplitude << endl;

	}
	else {
	myfile << "fractal_enable " << "false" << endl;
	}

	/* Water
	myfile << "water_height " << water_params->height << endl;
	myfile << "water_transparency " << water_params->transparency << endl;
	myfile << "water_depth_alpha_factor " << water_params->depth_alpha_factor << endl;
	myfile << "water_depth_color_factor " << water_params->depth_color_factor << endl;
	myfile << "water_color " << water_params->color[0] << ' ' << water_params->color[1] << ' ' << water_params->color[2] << endl;

	myfile.close();
	std::cout << "[Info] Data saved to " << file_name << endl;
	}
	else {
	std::cout << "[Error] Could not save data: the file " << file_name << " could not be opened." << endl;
	}*/
}

void loadFromFile(string file_name, NoiseParams *noise_params, WaterParams *water_params) {
	/*string line;
	ifstream myfile(file_name);
	if (myfile.is_open())
	{

	int line_no = 0;

	while (getline(myfile, line))
	{
	line_no++;

	if (line_no == 1) {
	if (line.compare(IO_HEADER_STRING)) {
	// the first line doesn't match the header -> illegal format
	std::cout << "Error: Illegal header. Aborting load." << endl;
	return;
	}
	}
	string str = line;

	// construct a stream from the string
	stringstream strstr(str);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	istream_iterator<string> it(strstr);
	istream_iterator<string> end;
	vector<string> results(it, end);

	/* Load fractal
	if (!results[0].compare("fractal_enable")) {
	if (!results[1].compare("true")) {
	fractal_params->enable = true;
	}
	else {
	}
	}
	else if (!results[0].compare("fractal_H")) {
	fractal_params->H = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("fractal_lacunarity")) {
	fractal_params->lacunarity = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("fractal_octaves")) {
	fractal_params->octaves = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("fractal_offset")) {
	fractal_params->offset = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("fractal_amplitude")) {
	fractal_params->amplitude = ::atof(results[1].c_str());
	}

	/* Load noise
	else if (!results[0].compare("noise_type")) {
	int type = ::atoi(results[1].c_str());
	switch (type) {
	case 0: noise_params->type = COPY_TEXTURE;
	break;
	case 1: noise_params->type = NO_NOISE;
	break;
	case 2: noise_params->type = RANDOM_NOISE;
	break;
	case 3: noise_params->type = PERLIN_NOISE;
	break;
	case 4: noise_params->type = PERLIN_NOISE_ABS;
	break;
	default:
	std::cout << "[Error] Unkown NoiseType" << endl;
	break;
	}

	}
	else if (!results[0].compare("noise_width")) {
	noise_params->width = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("noise_height")) {
	noise_params->height = ::atoi(results[1].c_str());
	}
	else if (!results[0].compare("noise_offset")) {
	noise_params->offset = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("noise_amplitude")) {
	noise_params->amplitude = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("noise_seed")) {
	noise_params->seed = ::atof(results[1].c_str());
	}

	/* Load water
	else if (!results[0].compare("water_height")) {
	water_params->height = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_transparency")) {
	water_params->transparency = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_depth_alpha_factor")) {
	water_params->depth_alpha_factor = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_depth_color_factor")) {
	water_params->depth_color_factor = ::atof(results[1].c_str());
	}
	else if (!results[0].compare("water_color")) {
	water_params->color = vec3(::atof(results[1].c_str()), ::atof(results[2].c_str()), ::atof(results[3].c_str()));
	}
	}

	myfile.close();
	std::cout << "[Info] Data loaded from " << file_name << endl;
	}
	else {
	std::cout << "[Error] Could not load data: the file" << file_name << " could not be opened." << endl;
	}*/
}

bool save_screenshot(string filename, int w, int h)
{

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	int nSize = w*h * 3;

	// 3 channels per Pixel
	char* dataBuffer = (char*)malloc(nSize*sizeof(char));

	if (!dataBuffer) return false;

	glReadPixels((GLint)0, (GLint)0,
		(GLint)w, (GLint)h,
		GL_BGR, GL_UNSIGNED_BYTE, dataBuffer);

	FILE *filePtr = fopen(filename.c_str(), "wb");
	if (!filePtr) return false;

	unsigned char TGAheader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	unsigned char header[6] = { w % 256, w / 256,
		h % 256, h / 256,
		24, 0 };
	// Write headers
	fwrite(TGAheader, sizeof(unsigned char), 12, filePtr);
	fwrite(header, sizeof(unsigned char), 6, filePtr);

	// Write image data
	fwrite(dataBuffer, sizeof(GLubyte), nSize, filePtr);

	fclose(filePtr);
	delete[] dataBuffer;

	return true;
}

string get_unique_name() {
	std::stringstream ss;

	time_t t = time(0);
	struct tm * now = localtime(&t);

	ss << (now->tm_year + 1900) << '-'
		<< (now->tm_mon + 1) << '-'
		<< now->tm_mday << '-'
		<< now->tm_hour << '-'
		<< now->tm_min << '-'
		<< now->tm_sec
		<< ".tga";

	return ss.str();
}<|endoftext|>


<commit_before><commit_msg>Fixed Vector2 to Integer2 cast in Application.<commit_after><|endoftext|>


<commit_before>/******************************************************************************
*	Motor Calibration tool:  Set motor PWM pulse widths to any value in us
******************************************************************************/

#include "MotorCalibration.h"
#include <signal.h>

//////////////////////
// Global Variables //
//////////////////////

// Stop main loop?
int stoploop = 0;

/******************************************************************************
* void ctrlC(int signo)
*
* Control-C Handler
******************************************************************************/
void ctroC(int signo)
{
	if (signo == SIGINT)
	{
		stoploop = 1;
		printf("\nReceived SIGINT Ctrl-C\n");
	}
}

/******************************************************************************
* Main Function
******************************************************************************/

int main()
{
	// Initialize WiringPi
 	wiringPiSetupGpio();

	// Setup ctrl-c catcher
	signal(SIGINT, ctrlC);

	int fd = pca9685Setup(PIN_BASE, PCA9685_ADDR, HERTZ);
 	pca9685PWMReset(fd);
 	for( int i = 0; i < 3; i++ )
 	{
		pwmWrite (PIN_BASE+i, 2674);
		printf("Initialized motor at pin_base: %i\n", PIN_BASE+i);
	}

	// Run main while loop, wait until it's time to stop
	while(!stoploop)
	{
		int motornum = 0, motoroutput;

		//std::cout << "Input motor number: ";
		//std::cin  >> motornum;

		std::cout << "Input motor output: ";
		std::cin  >> motoroutput;

		// Spin those motors
		//pwmWrite(motornum + PIN_BASE, motoroutput);
		pwmWrite(PIN_BASE + 0, motoroutput);
		pwmWrite(PIN_BASE + 1, motoroutput);

		std::cout << "Set Motor " << motornum << " to " << motoroutput << std::endl << std::endl;
	}

	// Shut off motors
	pwmWrite(PIN_BASE + 0, 2647);
	pwmWrite(PIN_BASE + 1, 2647);
	pwmWrite(PIN_BASE + 2, 2647);

	return 0;
}
<commit_msg>motorcalibration exits cleanly, but still need to quit to end program<commit_after>/******************************************************************************
*	Motor Calibration tool:  Set motor PWM pulse widths to any value in us
******************************************************************************/

#include "MotorCalibration.h"
#include <signal.h>

//////////////////////
// Global Variables //
//////////////////////

// Stop main loop?
int stoploop = 0;

/******************************************************************************
* void ctrlC(int signo)
*
* Control-C Handler
******************************************************************************/
void ctrlC(int signo)
{
	if (signo == SIGINT)
	{
		stoploop = 1;
		printf("\nReceived SIGINT Ctrl-C\n");

 	  for( int i = 0; i < 3; i++ )
  	{
		  pwmWrite (300+i, 2674);
		  printf("Motor zeroed at pin_base: %i\n", PIN_BASE+i);
	  }
    printf("exited cleanly\n");
	}
}

/******************************************************************************
* Main Function
******************************************************************************/

int main()
{
	// Initialize WiringPi
 	wiringPiSetupGpio();

	// Setup ctrl-c catcher
	signal(SIGINT, ctrlC);

  int fd = pca9685Setup(PIN_BASE, PCA9685_ADDR, HERTZ);
 	pca9685PWMReset(fd);
 	for( int i = 0; i < 3; i++ )
 	{
		pwmWrite (PIN_BASE+i, 2674);
		printf("Initialized motor at pin_base: %i\n", PIN_BASE+i);
	}

	// Run main while loop, wait until it's time to stop
	while(!stoploop)
	{
		int motornum = 0, motoroutput;

		//std::cout << "Input motor number: ";
		//std::cin  >> motornum;

		std::cout << "Input motor output: ";
		std::cin  >> motoroutput;

		// Spin those motors
		//pwmWrite(motornum + PIN_BASE, motoroutput);
		pwmWrite(PIN_BASE + 0, motoroutput);
		pwmWrite(PIN_BASE + 1, motoroutput);

		std::cout << "Set Motor " << motornum << " to " << motoroutput << std::endl << std::endl;
	}

	// Shut off motors
	pwmWrite(PIN_BASE + 0, 2647);
	pwmWrite(PIN_BASE + 1, 2647);
	pwmWrite(PIN_BASE + 2, 2647);

	return 0;
}

<|endoftext|>


<commit_before>
#include "cameraManager.h"

#define STRINGIFY(s) #s

void cameraManager::setup(){

	useSideCamera = false;
	currentCamera = &easyCam;

    string fragShaderSrc = STRINGIFY(

                                     uniform sampler2DRect tex0; // line image
                                     uniform sampler2DRect tex1; // rock image

                                     void main(void){
                                         vec2 st = gl_TexCoord[0].st;
                                         vec4 colorA = texture2DRect(tex0, st);
                                         vec4 colorB = texture2DRect(tex1, st);

                                         if (colorA.x > 0.01){
                                             gl_FragColor = vec4(colorB.x, colorB.y, colorB.z, colorA.x);
                                         } else {
                                             discard;
                                         }
                                     }

                                     );
    shader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragShaderSrc);
    shader.linkProgram();

}

void cameraManager::update(){
    if(!useSideCamera){
		currentCamera = &baseCamera;
	}
	else{
		//update camera positions;
		ofVec3f center = baseCamera.screenToWorld( ofPoint(1920/2,1080) / 2 );
		ofVec3f camP = baseCamera.getPosition();

		center = camP + (center - camP).normalize() * 351*2;

		sideCam.setPosition(center + ofVec3f(1920,0,0));
		sideCam.lookAt(center,ofVec3f(0,1,0));

		topCamera.setPosition(center + ofVec3f(0,1080, 0));
		topCamera.lookAt(center,ofVec3f(1,0,0));

	}

}

void cameraManager::drawCameraInternals(ofImage &person, ofImage &mask, ofImage &backplate){

    ofPoint a,b,c,d, e;

    ofRectangle window;
    window.set(0,0,1920, 1080);

    a = baseCamera.screenToWorld( ofPoint(0,1080), window);
    b = baseCamera.screenToWorld( ofPoint(1920,1080), window);
    c = baseCamera.screenToWorld( ofPoint(0,0), window);
    d = baseCamera.screenToWorld( ofPoint(1920,0), window);

    ofPoint camP = baseCamera.getPosition();

    ofPoint aFar = camP + (a - camP).normalize() * 351*7;
    ofPoint bFar = camP + (b - camP).normalize() * 351*7;
    ofPoint cFar = camP + (c - camP).normalize() * 351*7;
    ofPoint dFar = camP + (d - camP).normalize() * 351*7;

    a = camP + (a - camP).normalize() * 351*5;
    b = camP + (b - camP).normalize() * 351*5;
    c = camP + (c - camP).normalize() * 351*5;
    d = camP + (d - camP).normalize() * 351*5;
    e = camP + (e - camP).normalize() * 351*4;

    // draw the backplate:

    backplate.bind();
    ofMesh mesh;
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    mesh.addVertex( aFar) ;
    mesh.addTexCoord(   ofPoint(0,backplate.getHeight()));
    mesh.addVertex(  bFar) ;
    mesh.addTexCoord(   ofPoint(backplate.getWidth(),backplate.getHeight()));
    mesh.addVertex(  cFar) ;
    mesh.addTexCoord(   ofPoint(0,0));
    mesh.addVertex(  dFar ) ;
    mesh.addTexCoord(   ofPoint(backplate.getWidth(), 0));
    mesh.draw();
    backplate.unbind();

    // figure out a Z distance.

    shader.begin();
    shader.setUniformTexture("tex0", mask, 1);
    shader.setUniformTexture("tex1", person, 2);

    //frame.mask.bind();
    mesh.clear();
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    mesh.addVertex( a) ;
    mesh.addTexCoord(   ofPoint(0,person.getHeight()));
    mesh.addVertex(  b) ;
    mesh.addTexCoord(   ofPoint(person.getWidth(),person.getHeight()));
    mesh.addVertex(  c) ;
    mesh.addTexCoord(   ofPoint(0,0));
    mesh.addVertex(  d ) ;
    mesh.addTexCoord(   ofPoint(person.getWidth(), 0));
    mesh.draw();
    //backplate.unbind();
    shader.end();

    ofLine( baseCamera.getPosition(), a);
    ofLine( baseCamera.getPosition(), b);
    ofLine( baseCamera.getPosition(), c);
    ofLine( baseCamera.getPosition(), d);

}

void cameraManager::cameraStart(){

    if(useSideCamera){
		currentCamera->begin();
		ofPushStyle();
		ofPushMatrix();
		ofNoFill();
		ofColor(255,0,0);
        //		ofDrawSphere(depthToRGBTranslation, 10);
		ofNode n;
		n.setPosition(CCM.depthToRGBTranslation);
		n.draw();
		ofColor(0,250,0);
		ofSphere(0,0,0,10);
		ofFill();
		ofSetColor(255,0,0);
		if(ofGetKeyPressed('m')){
			ofMultMatrix(CCM.extrinsics);
		}
		ofSetLineWidth(5);
		ofLine(ofVec3f(0,0,0), ofVec3f(0,0,-100));
		ofPopMatrix();
		ofPopStyle();
        ofEnableDepthTest();
	}
	else{
		ofVec3f camPos(0,0,0);
		camPos = CCM.extrinsics * camPos;
		baseCamera.setTransformMatrix(CCM.extrinsics);
        baseCamera.setFov( CCM.rgbCalibration.getDistortedIntrinsics().getFov().y );
		baseCamera.begin(ofRectangle(0,0,1920, 1080));
        ofEnableDepthTest();
	}

    // this helps for easy cam, bring the scene nearer to 0,0,0

    if (currentCamera == &easyCam){

        ofRectangle window;
        window.set(0,0,1920, 1080);

        ofPoint e = baseCamera.screenToWorld( ofPoint(1920,1080) / 2.0, window);
        ofPoint camP = baseCamera.getPosition();
        e = camP + (e - camP).normalize() * 351*4;
        ofTranslate(-e.x, -e.y, -e.z);
    }

}

void cameraManager::cameraEnd(){
    if(useSideCamera){
		currentCamera->end();
	}
	else{
		baseCamera.end();
	}

}

void cameraManager::keyPressed(int key){
    if(key == ' '){
        useSideCamera = !useSideCamera;
        if (useSideCamera){
            //currentCamera = &easyCam;
        }
    }

    if(useSideCamera){
        if(key == OF_KEY_LEFT){
            if(currentCamera == &easyCam){
                currentCamera = &sideCam;
            }
            else if(currentCamera == &sideCam){
                currentCamera = &topCamera;
            }
            else {
                currentCamera = &easyCam;
            }
        }
        else if(key == OF_KEY_RIGHT){
            if(currentCamera == &easyCam){
                currentCamera = &topCamera;
            }
            else if(currentCamera == &topCamera){
                currentCamera = &sideCam;
            }
            else {
                currentCamera = &easyCam;
            }
        }
    }
}
<commit_msg>I need backplate drawn outside of camera to do some depth stuff with the rhonda line renderer (its needs a flat zdepth to composite ok)<commit_after>
#include "cameraManager.h"

#define STRINGIFY(s) #s

void cameraManager::setup(){

	useSideCamera = false;
	currentCamera = &easyCam;

    string fragShaderSrc = STRINGIFY(

                                     uniform sampler2DRect tex0; // line image
                                     uniform sampler2DRect tex1; // rock image

                                     void main(void){
                                         vec2 st = gl_TexCoord[0].st;
                                         vec4 colorA = texture2DRect(tex0, st);
                                         vec4 colorB = texture2DRect(tex1, st);

                                         if (colorA.x > 0.01){
                                             gl_FragColor = vec4(colorB.x, colorB.y, colorB.z, colorA.x);
                                         } else {
                                             discard;
                                         }
                                     }

                                     );
    shader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragShaderSrc);
    shader.linkProgram();

}

void cameraManager::update(){
    if(!useSideCamera){
		currentCamera = &baseCamera;
	}
	else{
		//update camera positions;
		ofVec3f center = baseCamera.screenToWorld( ofPoint(1920/2,1080) / 2 );
		ofVec3f camP = baseCamera.getPosition();

		center = camP + (center - camP).normalize() * 351*2;

		sideCam.setPosition(center + ofVec3f(1920,0,0));
		sideCam.lookAt(center,ofVec3f(0,1,0));

		topCamera.setPosition(center + ofVec3f(0,1080, 0));
		topCamera.lookAt(center,ofVec3f(1,0,0));

	}

}

void cameraManager::drawCameraInternals(ofImage &person, ofImage &mask, ofImage &backplate){

    ofPoint a,b,c,d, e;

    ofRectangle window;
    window.set(0,0,1920, 1080);

    a = baseCamera.screenToWorld( ofPoint(0,1080), window);
    b = baseCamera.screenToWorld( ofPoint(1920,1080), window);
    c = baseCamera.screenToWorld( ofPoint(0,0), window);
    d = baseCamera.screenToWorld( ofPoint(1920,0), window);

    ofPoint camP = baseCamera.getPosition();

    ofPoint aFar = camP + (a - camP).normalize() * 351*7;
    ofPoint bFar = camP + (b - camP).normalize() * 351*7;
    ofPoint cFar = camP + (c - camP).normalize() * 351*7;
    ofPoint dFar = camP + (d - camP).normalize() * 351*7;

    a = camP + (a - camP).normalize() * 351*5;
    b = camP + (b - camP).normalize() * 351*5;
    c = camP + (c - camP).normalize() * 351*5;
    d = camP + (d - camP).normalize() * 351*5;
    e = camP + (e - camP).normalize() * 351*4;

    // draw the backplate:

     ofMesh mesh;
    /*
    // I want to draw the backplay flat with no depth b/c of how the line renderer needs to fuck with depth.
    backplate.bind();
    ofMesh mesh;
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    mesh.addVertex( aFar) ;
    mesh.addTexCoord(   ofPoint(0,backplate.getHeight()));
    mesh.addVertex(  bFar) ;
    mesh.addTexCoord(   ofPoint(backplate.getWidth(),backplate.getHeight()));
    mesh.addVertex(  cFar) ;
    mesh.addTexCoord(   ofPoint(0,0));
    mesh.addVertex(  dFar ) ;
    mesh.addTexCoord(   ofPoint(backplate.getWidth(), 0));
    mesh.draw();
    backplate.unbind();
    */
    // figure out a Z distance.

    shader.begin();
    shader.setUniformTexture("tex0", mask, 1);
    shader.setUniformTexture("tex1", person, 2);

    //frame.mask.bind();
    mesh.clear();
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    mesh.addVertex( a) ;
    mesh.addTexCoord(   ofPoint(0,person.getHeight()));
    mesh.addVertex(  b) ;
    mesh.addTexCoord(   ofPoint(person.getWidth(),person.getHeight()));
    mesh.addVertex(  c) ;
    mesh.addTexCoord(   ofPoint(0,0));
    mesh.addVertex(  d ) ;
    mesh.addTexCoord(   ofPoint(person.getWidth(), 0));
    mesh.draw();
    //backplate.unbind();
    shader.end();

    ofLine( baseCamera.getPosition(), a);
    ofLine( baseCamera.getPosition(), b);
    ofLine( baseCamera.getPosition(), c);
    ofLine( baseCamera.getPosition(), d);

}

void cameraManager::cameraStart(){

    if(useSideCamera){
		currentCamera->begin();
		ofPushStyle();
		ofPushMatrix();
		ofNoFill();
		ofColor(255,0,0);
        //		ofDrawSphere(depthToRGBTranslation, 10);
		ofNode n;
		n.setPosition(CCM.depthToRGBTranslation);
		n.draw();
		ofColor(0,250,0);
		ofSphere(0,0,0,10);
		ofFill();
		ofSetColor(255,0,0);
		if(ofGetKeyPressed('m')){
			ofMultMatrix(CCM.extrinsics);
		}
		ofSetLineWidth(5);
		ofLine(ofVec3f(0,0,0), ofVec3f(0,0,-100));
		ofPopMatrix();
		ofPopStyle();
        ofEnableDepthTest();
	}
	else{
		ofVec3f camPos(0,0,0);
		camPos = CCM.extrinsics * camPos;
		baseCamera.setTransformMatrix(CCM.extrinsics);
        baseCamera.setFov( CCM.rgbCalibration.getDistortedIntrinsics().getFov().y );
		baseCamera.begin(ofRectangle(0,0,1920, 1080));
        ofEnableDepthTest();
	}

    // this helps for easy cam, bring the scene nearer to 0,0,0

    if (currentCamera == &easyCam){

        ofRectangle window;
        window.set(0,0,1920, 1080);

        ofPoint e = baseCamera.screenToWorld( ofPoint(1920,1080) / 2.0, window);
        ofPoint camP = baseCamera.getPosition();
        e = camP + (e - camP).normalize() * 351*4;
        ofTranslate(-e.x, -e.y, -e.z);
    }

}

void cameraManager::cameraEnd(){
    if(useSideCamera){
		currentCamera->end();
	}
	else{
		baseCamera.end();
	}

}

void cameraManager::keyPressed(int key){
    if(key == ' '){
        useSideCamera = !useSideCamera;
        if (useSideCamera){
            //currentCamera = &easyCam;
        }
    }

    if(useSideCamera){
        if(key == OF_KEY_LEFT){
            if(currentCamera == &easyCam){
                currentCamera = &sideCam;
            }
            else if(currentCamera == &sideCam){
                currentCamera = &topCamera;
            }
            else {
                currentCamera = &easyCam;
            }
        }
        else if(key == OF_KEY_RIGHT){
            if(currentCamera == &easyCam){
                currentCamera = &topCamera;
            }
            else if(currentCamera == &topCamera){
                currentCamera = &sideCam;
            }
            else {
                currentCamera = &easyCam;
            }
        }
    }
}
<|endoftext|>