<commit_before>#include "geographic-settings.hh"

// ----------------------------------------------------------------------

static const char* const SETTINGS_DEFAULT = R"({ "_":"-*- js-indent-level: 2 -*-",
  "coloring": {"N": "clade"},
  "coloring?": [
    {"N": "continent", "?continent_color": {"EUROPE": {"fill": "green", "outline": "black", "outline_width": 0}}},
    {"N": "clade", "?clade_color": {"SEQUENCED": {"fill": "yellow", "outline": "black", "outline_width": 0}}},
    {"N": "lineage", "?lineage_color": {"VICTORIA_2DEL": {"fill": "#23a8d1", "outline": "black", "outline_width": 0}, "VICTORIA_3DEL": {"fill": "#80FF00", "outline": "black", "outline_width": 0}}},
    {"N": "lineage-deletion-mutants", "?lineage_color": {"VICTORIA_2DEL": {"fill": "#23a8d1", "outline": "black", "outline_width": 0}, "VICTORIA_3DEL": {"fill": "#80FF00", "outline": "black", "outline_width": 0}}},
    {"N": "amino-acid", "apply": [{"sequenced": true, "color": "red"}, {"aa": ["156N" ,"155G"], "color": "blue"}], "report": false}
  ],
  "???color_override?": {"B": {"?": "B/Vic deletion mutants", "?B/DOMINICAN REPUBLIC/9932/2016": "#00FFFF"}},
  "start_date": "2017-01-01",
  "end_date": "",
  "point_size_in_pixels": 4.0,
  "point_density": 0.8,
  "continent_outline_color": "grey63",
  "continent_outline_width": 0.5,
  "output_image_width": 800,

  "title_text": "",
  "title": {"offset": [0, 0], "text_size": 20, "background": "transparent", "border_color": "black", "border_width": 0, "text_color": "black", "padding": 10.0},

  "continent_color": {
    "EUROPE":            {"fill": "green",       "outline": "black", "outline_width": 0},
    "CENTRAL-AMERICA":   {"fill": "#AAF9FF",     "outline": "black", "outline_width": 0},
    "MIDDLE-EAST":       {"fill": "#8000FF",     "outline": "black", "outline_width": 0},
    "NORTH-AMERICA":     {"fill": "blue4",       "outline": "black", "outline_width": 0},
    "AFRICA":            {"fill": "darkorange1", "outline": "black", "outline_width": 0},
    "ASIA":              {"fill": "red",         "outline": "black", "outline_width": 0},
    "RUSSIA":            {"fill": "maroon",      "outline": "black", "outline_width": 0},
    "AUSTRALIA-OCEANIA": {"fill": "hotpink",     "outline": "black", "outline_width": 0},
    "SOUTH-AMERICA":     {"fill": "turquoise",   "outline": "black", "outline_width": 0},
    "ANTARCTICA":        {"fill": "grey50",      "outline": "black", "outline_width": 0},
    "UNKNOWN":           {"fill": "grey50",      "outline": "black", "outline_width": 0},
    "":                  {"fill": "grey50",      "outline": "black", "outline_width": 0}
  },

  "clade_color": {
    "?": "========== sequenced but not in any clade",
    "":              {"fill": "grey50",          "outline": "black", "outline_width": 0},
    "SEQUENCED":     {"fill": "yellow",          "outline": "black", "outline_width": 0},

    "?": "========== H3",
    "3C.3":           {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "3C.2A":             {"fill": "red",             "outline": "black", "outline_width": 0},
    "3C.2A1":            {"fill": "#ffab91",         "outline": "black", "outline_width": 0},
    "3C.2A1A":           {"fill": "#E040FB",         "outline": "black", "outline_width": 0},
    "3C.2A1B":           {"fill": "#CD5C5C",         "outline": "black", "outline_width": 0},
    "3C.2A2":            {"fill": "#EEB422",         "outline": "black", "outline_width": 0},
    "3C.3A":             {"fill": "green",           "outline": "black", "outline_width": 0},
    "3C.3B":             {"fill": "blue",            "outline": "black", "outline_width": 0},

    "?": "========== H1pdm",
    "6B1":           {"fill": "blue",            "outline": "black", "outline_width": 0},
    "6B2":           {"fill": "red",             "outline": "black", "outline_width": 0},

    "?": "========== B/Yam",
    "Y2":            {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "Y3":            {"fill": "red",             "outline": "black", "outline_width": 0},

    "?": "========== B/Vic",
    "V1":             {"fill": "blue",            "outline": "black", "outline_width": 0},
    "V1A":            {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "V1B":            {"fill": "red",             "outline": "black", "outline_width": 0},
    "2DEL2017":       {"fill": "#000080",         "outline": "black", "outline_width": 0},
    "3DEL2017": {"fill": "#46f0f0",         "outline": "black", "outline_width": 0}
  },

  "lineage_color": {
    "YAMAGATA":      {"fill": "#d10000",         "outline": "black", "outline_width": 0},
    "VICTORIA":      {"fill": "#2700b7",         "outline": "black", "outline_width": 0},
    "VICTORIA_2DEL":  {"fill": "#23a8d1",         "outline": "black", "outline_width": 0},
    "VICTORIA_3DEL":  {"fill": "#BF3EFF",         "outline": "black", "outline_width": 0}
  },

  "?": "draw VICTORIA_2DEL on top of VICTORIA",
  "priority": ["YAMAGATA", "VICTORIA", "VICTORIA_2DEL"]

}
)";

rjson::value geographic_settings_default()
{
    try {
        return rjson::parse_string(SETTINGS_DEFAULT);
    }
    catch (std::exception& err) {
        std::cerr << "ERROR: parsing SETTINGS_DEFAULT: " << err.what() << '\n';
        throw;
    }
}

// ----------------------------------------------------------------------

std::string geographic_settings_default_raw()
{
    return SETTINGS_DEFAULT;

} // geographic_settings_default_raw

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>Do not mark 3C.2a and 3C.2a1 on H1 geo epi ts, it must have lower priority.<commit_after>#include "geographic-settings.hh"

// ----------------------------------------------------------------------

static const char* const SETTINGS_DEFAULT = R"({ "_":"-*- js-indent-level: 2 -*-",
  "coloring": {"N": "clade"},
  "coloring?": [
    {"N": "continent", "?continent_color": {"EUROPE": {"fill": "green", "outline": "black", "outline_width": 0}}},
    {"N": "clade", "?clade_color": {"SEQUENCED": {"fill": "yellow", "outline": "black", "outline_width": 0}}},
    {"N": "lineage", "?lineage_color": {"VICTORIA_2DEL": {"fill": "#23a8d1", "outline": "black", "outline_width": 0}, "VICTORIA_3DEL": {"fill": "#80FF00", "outline": "black", "outline_width": 0}}},
    {"N": "lineage-deletion-mutants", "?lineage_color": {"VICTORIA_2DEL": {"fill": "#23a8d1", "outline": "black", "outline_width": 0}, "VICTORIA_3DEL": {"fill": "#80FF00", "outline": "black", "outline_width": 0}}},
    {"N": "amino-acid", "apply": [{"sequenced": true, "color": "red"}, {"aa": ["156N" ,"155G"], "color": "blue"}], "report": false}
  ],
  "???color_override?": {"B": {"?": "B/Vic deletion mutants", "?B/DOMINICAN REPUBLIC/9932/2016": "#00FFFF"}},
  "start_date": "2017-01-01",
  "end_date": "",
  "point_size_in_pixels": 4.0,
  "point_density": 0.8,
  "continent_outline_color": "grey63",
  "continent_outline_width": 0.5,
  "output_image_width": 800,

  "title_text": "",
  "title": {"offset": [0, 0], "text_size": 20, "background": "transparent", "border_color": "black", "border_width": 0, "text_color": "black", "padding": 10.0},

  "continent_color": {
    "EUROPE":            {"fill": "green",       "outline": "black", "outline_width": 0},
    "CENTRAL-AMERICA":   {"fill": "#AAF9FF",     "outline": "black", "outline_width": 0},
    "MIDDLE-EAST":       {"fill": "#8000FF",     "outline": "black", "outline_width": 0},
    "NORTH-AMERICA":     {"fill": "blue4",       "outline": "black", "outline_width": 0},
    "AFRICA":            {"fill": "darkorange1", "outline": "black", "outline_width": 0},
    "ASIA":              {"fill": "red",         "outline": "black", "outline_width": 0},
    "RUSSIA":            {"fill": "maroon",      "outline": "black", "outline_width": 0},
    "AUSTRALIA-OCEANIA": {"fill": "hotpink",     "outline": "black", "outline_width": 0},
    "SOUTH-AMERICA":     {"fill": "turquoise",   "outline": "black", "outline_width": 0},
    "ANTARCTICA":        {"fill": "grey50",      "outline": "black", "outline_width": 0},
    "UNKNOWN":           {"fill": "grey50",      "outline": "black", "outline_width": 0},
    "":                  {"fill": "grey50",      "outline": "black", "outline_width": 0}
  },

  "clade_color": {
    "?": "========== sequenced but not in any clade",
    "":              {"fill": "grey50",          "outline": "black", "outline_width": 0},
    "SEQUENCED":     {"fill": "yellow",          "outline": "black", "outline_width": 0},

    "?": "========== H3",
    "3C.3":           {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "x 3C.2A":             {"fill": "red",             "outline": "black", "outline_width": 0},
    "x 3C.2A1":            {"fill": "#ffab91",         "outline": "black", "outline_width": 0},
    "3C.2A1A":           {"fill": "#E040FB",         "outline": "black", "outline_width": 0},
    "3C.2A1B":           {"fill": "#CD5C5C",         "outline": "black", "outline_width": 0},
    "3C.2A2":            {"fill": "#EEB422",         "outline": "black", "outline_width": 0},
    "3C.3A":             {"fill": "green",           "outline": "black", "outline_width": 0},
    "3C.3B":             {"fill": "blue",            "outline": "black", "outline_width": 0},

    "?": "========== H1pdm",
    "6B1":           {"fill": "blue",            "outline": "black", "outline_width": 0},
    "6B2":           {"fill": "red",             "outline": "black", "outline_width": 0},

    "?": "========== B/Yam",
    "Y2":            {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "Y3":            {"fill": "red",             "outline": "black", "outline_width": 0},

    "?": "========== B/Vic",
    "V1":             {"fill": "blue",            "outline": "black", "outline_width": 0},
    "V1A":            {"fill": "cornflowerblue",  "outline": "black", "outline_width": 0},
    "V1B":            {"fill": "red",             "outline": "black", "outline_width": 0},
    "2DEL2017":       {"fill": "#000080",         "outline": "black", "outline_width": 0},
    "3DEL2017": {"fill": "#46f0f0",         "outline": "black", "outline_width": 0}
  },

  "lineage_color": {
    "YAMAGATA":      {"fill": "#d10000",         "outline": "black", "outline_width": 0},
    "VICTORIA":      {"fill": "#2700b7",         "outline": "black", "outline_width": 0},
    "VICTORIA_2DEL":  {"fill": "#23a8d1",         "outline": "black", "outline_width": 0},
    "VICTORIA_3DEL":  {"fill": "#BF3EFF",         "outline": "black", "outline_width": 0}
  },

  "?": "draw VICTORIA_2DEL on top of VICTORIA",
  "priority": ["YAMAGATA", "VICTORIA", "VICTORIA_2DEL"]

}
)";

rjson::value geographic_settings_default()
{
    try {
        return rjson::parse_string(SETTINGS_DEFAULT);
    }
    catch (std::exception& err) {
        std::cerr << "ERROR: parsing SETTINGS_DEFAULT: " << err.what() << '\n';
        throw;
    }
}

// ----------------------------------------------------------------------

std::string geographic_settings_default_raw()
{
    return SETTINGS_DEFAULT;

} // geographic_settings_default_raw

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONALS_L2_HH
#define DUNE_GDT_FUNCTIONALS_L2_HH

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/localfunctional/codim0.hh>
#include <dune/gdt/localfunctional/codim1.hh>
#include <dune/gdt/localevaluation/product.hh>
#include <dune/gdt/assembler/system.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Functionals {

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType,
          class LocalEvaluationType                                              = LocalEvaluation::Product<FunctionType>>
class L2Volume;

namespace internal {

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp, class LocalEvaluationType>
class L2VolumeTraits
{
  static_assert(std::is_base_of<Stuff::LocalizableFunctionInterface<
                                    typename FunctionType::EntityType, typename FunctionType::DomainFieldType,
                                    FunctionType::dimDomain, typename FunctionType::RangeFieldType,
                                    FunctionType::dimRange, FunctionType::dimRangeCols>,
                                FunctionType>::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits, SpaceImp::dimDomain, SpaceImp::dimRange,
                                               SpaceImp::dimRangeCols>,
                                SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");

public:
  typedef L2Volume<FunctionType, VectorImp, SpaceImp, GridViewImp, LocalEvaluationType> derived_type;
  typedef VectorImp VectorType;
  typedef SpaceImp SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
}; // class L2VolumeTraits

} // namespace internal

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp, class LocalEvaluationType>
class L2Volume : public Functionals::VectorBased<internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp,
                                                                          GridViewImp, LocalEvaluationType>>,
                 public SystemAssembler<SpaceImp, GridViewImp, SpaceImp>
{
  typedef Functionals::VectorBased<internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp, GridViewImp,
                                                            LocalEvaluationType>> FunctionalBaseType;
  typedef SystemAssembler<SpaceImp, GridViewImp, SpaceImp> AssemblerBaseType;

  typedef LocalFunctional::Codim0Integral<LocalEvaluationType> LocalFunctionalType;
  typedef LocalAssembler::Codim0Vector<LocalFunctionalType> LocalAssemblerType;

public:
  typedef internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp, GridViewImp, LocalEvaluationType> Traits;
  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType SpaceType;
  typedef typename Traits::GridViewType GridViewType;

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc, const GridViewType& grd_vw)
    : FunctionalBaseType(vec, spc, grd_vw)
    , AssemblerBaseType(spc, grd_vw)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup();
  }

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc)
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup();
  }

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc,
           const LocalFunctionalType localFunctional)
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(localFunctional)
    , local_assembler_(local_functional_)
  {
    setup();
  }
  virtual void assemble() override final
  {
    AssemblerBaseType::assemble();
  }

private:
  void setup()
  {
    this->add(local_assembler_, this->vector());
  }

  const FunctionType& function_;
  const LocalFunctionalType local_functional_;
  const LocalAssemblerType local_assembler_;
}; // class L2Volume

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType>
class L2Face;

namespace internal {

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp>
class L2FaceTraits
{
  static_assert(std::is_base_of<Stuff::LocalizableFunctionInterface<
                                    typename FunctionType::EntityType, typename FunctionType::DomainFieldType,
                                    FunctionType::dimDomain, typename FunctionType::RangeFieldType,
                                    FunctionType::dimRange, FunctionType::dimRangeCols>,
                                FunctionType>::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits, SpaceImp::dimDomain, SpaceImp::dimRange,
                                               SpaceImp::dimRangeCols>,
                                SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");

public:
  typedef L2Face<FunctionType, VectorImp, SpaceImp, GridViewImp> derived_type;
  typedef VectorImp VectorType;
  typedef SpaceImp SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
}; // class L2FaceTraits

} // namespace internal

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp>
class L2Face : public Functionals::VectorBased<internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp>>,
               public SystemAssembler<SpaceImp, GridViewImp, SpaceImp>
{
  typedef Functionals::VectorBased<internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp>>
      FunctionalBaseType;
  typedef SystemAssembler<SpaceImp, GridViewImp, SpaceImp> AssemblerBaseType;

  typedef LocalFunctional::Codim1Integral<LocalEvaluation::Product<FunctionType>> LocalFunctionalType;
  typedef LocalAssembler::Codim1Vector<LocalFunctionalType> LocalAssemblerType;

public:
  typedef internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp> Traits;

  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType SpaceType;
  typedef typename Traits::GridViewType GridViewType;

  L2Face(const FunctionType& function, VectorType& vec, const SpaceType& spc, const GridViewType& grd_vw,
         const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections =
             new Stuff::Grid::ApplyOn::AllIntersections<GridViewType>())
    : FunctionalBaseType(vec, spc, grd_vw)
    , AssemblerBaseType(spc, grd_vw)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup(which_intersections);
  }

  L2Face(const FunctionType& function, VectorType& vec, const SpaceType& spc,
         const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections =
             new Stuff::Grid::ApplyOn::AllIntersections<GridViewType>())
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup(which_intersections);
  }

  virtual void assemble() override final
  {
    AssemblerBaseType::assemble();
  }

private:
  void setup(const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections)
  {
    this->add(local_assembler_, this->vector(), which_intersections);
  }

  const FunctionType& function_;
  const LocalFunctionalType local_functional_;
  const LocalAssemblerType local_assembler_;
}; // class L2Face

} // namespace Functionals
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONALS_L2_HH
<commit_msg>[functions.l2] group traits<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_FUNCTIONALS_L2_HH
#define DUNE_GDT_FUNCTIONALS_L2_HH

#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/la/container/interfaces.hh>

#include <dune/gdt/localfunctional/codim0.hh>
#include <dune/gdt/localfunctional/codim1.hh>
#include <dune/gdt/localevaluation/product.hh>
#include <dune/gdt/assembler/system.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Functionals {

// forwards
template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType,
          class LocalEvaluationType                                              = LocalEvaluation::Product<FunctionType>>
class L2Volume;

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp = typename SpaceImp::GridViewType>
class L2Face;

namespace internal {

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp, class LocalEvaluationType>
class L2VolumeTraits
{
  static_assert(std::is_base_of<Stuff::LocalizableFunctionInterface<
                                    typename FunctionType::EntityType, typename FunctionType::DomainFieldType,
                                    FunctionType::dimDomain, typename FunctionType::RangeFieldType,
                                    FunctionType::dimRange, FunctionType::dimRangeCols>,
                                FunctionType>::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(std::is_base_of<SpaceInterface<typename SpaceImp::Traits, SpaceImp::dimDomain, SpaceImp::dimRange,
                                               SpaceImp::dimRangeCols>,
                                SpaceImp>::value,
                "SpaceImp has to be derived from SpaceInterface!");

public:
  typedef L2Volume<FunctionType, VectorImp, SpaceImp, GridViewImp, LocalEvaluationType> derived_type;
  typedef VectorImp VectorType;
  typedef SpaceImp SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
}; // class L2VolumeTraits

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp>
class L2FaceTraits
{
  static_assert(Stuff::is_localizable_function<FunctionType>::value,
                "FunctionType has to be derived from Stuff::LocalizableFunctionInterface!");
  static_assert(is_space<SpaceImp>::value, "SpaceImp has to be derived from SpaceInterface!");

public:
  typedef L2Face<FunctionType, VectorImp, SpaceImp, GridViewImp> derived_type;
  typedef VectorImp VectorType;
  typedef SpaceImp SpaceType;
  typedef GridViewImp GridViewType;
  typedef typename VectorType::ScalarType ScalarType;
}; // class L2FaceTraits

} // namespace internal

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp, class LocalEvaluationType>
class L2Volume : public Functionals::VectorBased<internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp,
                                                                          GridViewImp, LocalEvaluationType>>,
                 public SystemAssembler<SpaceImp, GridViewImp, SpaceImp>
{
  typedef Functionals::VectorBased<internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp, GridViewImp,
                                                            LocalEvaluationType>> FunctionalBaseType;
  typedef SystemAssembler<SpaceImp, GridViewImp, SpaceImp> AssemblerBaseType;

  typedef LocalFunctional::Codim0Integral<LocalEvaluationType> LocalFunctionalType;
  typedef LocalAssembler::Codim0Vector<LocalFunctionalType> LocalAssemblerType;

public:
  typedef internal::L2VolumeTraits<FunctionType, VectorImp, SpaceImp, GridViewImp, LocalEvaluationType> Traits;
  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType SpaceType;
  typedef typename Traits::GridViewType GridViewType;

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc, const GridViewType& grd_vw)
    : FunctionalBaseType(vec, spc, grd_vw)
    , AssemblerBaseType(spc, grd_vw)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup();
  }

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc)
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup();
  }

  L2Volume(const FunctionType& function, VectorType& vec, const SpaceType& spc,
           const LocalFunctionalType localFunctional)
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(localFunctional)
    , local_assembler_(local_functional_)
  {
    setup();
  }
  virtual void assemble() override final
  {
    AssemblerBaseType::assemble();
  }

private:
  void setup()
  {
    this->add(local_assembler_, this->vector());
  }

  const FunctionType& function_;
  const LocalFunctionalType local_functional_;
  const LocalAssemblerType local_assembler_;
}; // class L2Volume

template <class FunctionType, class VectorImp, class SpaceImp, class GridViewImp>
class L2Face : public Functionals::VectorBased<internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp>>,
               public SystemAssembler<SpaceImp, GridViewImp, SpaceImp>
{
  typedef Functionals::VectorBased<internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp>>
      FunctionalBaseType;
  typedef SystemAssembler<SpaceImp, GridViewImp, SpaceImp> AssemblerBaseType;

  typedef LocalFunctional::Codim1Integral<LocalEvaluation::Product<FunctionType>> LocalFunctionalType;
  typedef LocalAssembler::Codim1Vector<LocalFunctionalType> LocalAssemblerType;

public:
  typedef internal::L2FaceTraits<FunctionType, VectorImp, SpaceImp, GridViewImp> Traits;

  typedef typename Traits::VectorType VectorType;
  typedef typename Traits::SpaceType SpaceType;
  typedef typename Traits::GridViewType GridViewType;

  L2Face(const FunctionType& function, VectorType& vec, const SpaceType& spc, const GridViewType& grd_vw,
         const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections =
             new Stuff::Grid::ApplyOn::AllIntersections<GridViewType>())
    : FunctionalBaseType(vec, spc, grd_vw)
    , AssemblerBaseType(spc, grd_vw)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup(which_intersections);
  }

  L2Face(const FunctionType& function, VectorType& vec, const SpaceType& spc,
         const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections =
             new Stuff::Grid::ApplyOn::AllIntersections<GridViewType>())
    : FunctionalBaseType(vec, spc)
    , AssemblerBaseType(spc)
    , function_(function)
    , local_functional_(function_)
    , local_assembler_(local_functional_)
  {
    setup(which_intersections);
  }

  virtual void assemble() override final
  {
    AssemblerBaseType::assemble();
  }

private:
  void setup(const Stuff::Grid::ApplyOn::WhichIntersection<GridViewType>* which_intersections)
  {
    this->add(local_assembler_, this->vector(), which_intersections);
  }

  const FunctionType& function_;
  const LocalFunctionalType local_functional_;
  const LocalAssemblerType local_assembler_;
}; // class L2Face

} // namespace Functionals
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_FUNCTIONALS_L2_HH
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_BASE_HH
#define DUNE_GDT_OPERATORS_BASE_HH

#include <dune/gdt/assembler/system.hh>
#include <dune/gdt/assembler/local/codim0.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

template <class Traits>
class MatrixBasedBase : public AssemblableOperatorInterface<Traits>
{
  typedef AssemblableOperatorInterface<Traits> InterfaceType;

public:
  typedef typename Traits::GridViewType GridViewType;
  typedef typename Traits::SourceSpaceType SourceSpaceType;
  typedef typename Traits::RangeSpaceType RangeSpaceType;
  typedef typename Traits::MatrixType MatrixType;

  typedef typename MatrixType::ScalarType FieldType;

private:
  typedef Stuff::LA::Solver<MatrixType> LinearSolverType;

public:
  using typename InterfaceType::EntityType;

  MatrixBasedBase(MatrixType& matrix, const SourceSpaceType& source_space, const RangeSpaceType& range_space,
                  const GridViewType& grid_view)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(grid_view)
    , assembled_(false)
  {
  }

  MatrixBasedBase(MatrixType& matrix, const SourceSpaceType& source_space, const RangeSpaceType& range_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {
  }

  MatrixBasedBase(MatrixType& matrix, const SourceSpaceType& source_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(source_space_)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

  virtual void assemble() = 0;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S>& source, Stuff::LA::VectorInterface<R>& range)
  {
    assemble();
    matrix_.mv(source.as_imp(), range.as_imp());
  } // ... apply(...)

  static std::vector<std::string> invert_options()
  {
    return LinearSolverType::options();
  }

  static Stuff::Common::ConfigTree invert_options(const std::string& type)
  {
    return LinearSolverType::options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R>& range, Stuff::LA::VectorInterface<S>& source,
                     const Stuff::Common::ConfigTree& opts)
  {
    assemble();
    LinearSolverType(matrix).apply(range.as_imp(), source.as_imp(), opts);
  } // ... apply_inverse(...)

private:
  MatrixType& matrix_;
  const SourceSpaceType& source_space_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  bool assembled_;
}; // class MatrixBasedBase

} // namespace Operators
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_BASE_HH
<commit_msg>[operators.base] MatrixBasedBase -> MatrixBased<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_OPERATORS_BASE_HH
#define DUNE_GDT_OPERATORS_BASE_HH

#include <dune/stuff/la/solver.hh>

#include "interfaces.hh"

namespace Dune {
namespace GDT {
namespace Operators {

template <class Traits>
class MatrixBased : public AssemblableOperatorInterface<Traits>
{
  typedef AssemblableOperatorInterface<Traits> BaseType;

public:
  using typename BaseType::GridViewType;
  using typename BaseType::SourceSpaceType;
  using typename BaseType::RangeSpaceType;
  using typename BaseType::MatrixType;

private:
  typedef Stuff::LA::Solver<MatrixType> LinearSolverType;

public:
  MatrixBased(MatrixType& matrix, const SourceSpaceType& source_space, const RangeSpaceType& range_space,
              const GridViewType& grid_view)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(grid_view)
    , assembled_(false)
  {
  }

  MatrixBased(MatrixType& matrix, const SourceSpaceType& source_space, const RangeSpaceType& range_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(range_space)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {
  }

  MatrixBased(MatrixType& matrix, const SourceSpaceType& source_space)
    : matrix_(matrix)
    , source_space_(source_space)
    , range_space_(source_space_)
    , grid_view_(*(source_space_.grid_view()))
    , assembled_(false)
  {
  }

  const GridViewType& grid_view() const
  {
    return grid_view_;
  }

  const RangeSpaceType& range_space() const
  {
    return range_space_;
  }

  const SourceSpaceType& source_space() const
  {
    return source_space_;
  }

  MatrixType& matrix()
  {
    return matrix_;
  }

  const MatrixType& matrix() const
  {
    return matrix_;
  }

  virtual void assemble() = 0;

  template <class S, class R>
  void apply(const Stuff::LA::VectorInterface<S>& source, Stuff::LA::VectorInterface<R>& range)
  {
    assemble();
    matrix_.mv(source.as_imp(), range.as_imp());
  } // ... apply(...)

  static std::vector<std::string> invert_options()
  {
    return LinearSolverType::options();
  }

  static Stuff::Common::ConfigTree invert_options(const std::string& type)
  {
    return LinearSolverType::options(type);
  }

  template <class R, class S>
  void apply_inverse(const Stuff::LA::VectorInterface<R>& range, Stuff::LA::VectorInterface<S>& source,
                     const Stuff::Common::ConfigTree& opts)
  {
    assemble();
    LinearSolverType(matrix).apply(range.as_imp(), source.as_imp(), opts);
  } // ... apply_inverse(...)

private:
  MatrixType& matrix_;
  const SourceSpaceType& source_space_;
  const RangeSpaceType& range_space_;
  const GridViewType& grid_view_;
  bool assembled_;
}; // class MatrixBased

} // namespace Operators
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_OPERATORS_BASE_HH
<|endoftext|>


<commit_before>//
//  LeastSquaresSolver.cpp
//  pvrtex
//
//  Created by Chirantan Ekbote on 11/14/12.
//
//

#include "../inc/Optimizer.h"

#define ROW(n)	1*n,	2*n,	3*n,	4*n,	3*n,	2*n,	1*n

namespace pvrtex {
  // Optimization window information
  const int Optimizer::window_width_ = 11;
  const int Optimizer::window_height_ = 11;
  const int Optimizer::matrix_rows_ = 121;
  const int Optimizer::matrix_cols_ = 8;
  const int Optimizer::offset_x_ = 4;
  const int Optimizer::offset_y_ = 4;

  // Weight matrices
  const float Optimizer::kTopLeft[] =
  {
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.25f), 0, 0, 0, 0,		// 4/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0
  };
  const float Optimizer::kTopRight[] =
  {
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.25f),		// 4/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0
  };
  const float Optimizer::kBottomLeft[] =
  {
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.25f), 0, 0, 0, 0,		// 4/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
  };
  const float Optimizer::kBottomRight[] =
  {
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.25f),		// 4/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.0625f)	// 1/16
  };

  Optimizer::Optimizer(Eigen::MatrixXi o, Eigen::MatrixXf m) :
  orig_(o),
  mod_(m),
  solv_(SVD)
  {
    dark_ = Eigen::MatrixXi(o.rows()>>2, o.cols()>>2);
    bright_ = Eigen::MatrixXi(o.rows()>>2, o.cols()>>2);
  }

  Optimizer::Optimizer(Eigen::MatrixXi o, Eigen::MatrixXf m, SOLVER s) :
  orig_(o),
  mod_(m),
  solv_(s)
  {
    dark_(o.rows()>>2, o.cols()>>2);
    bright_(o.rows()>>2, o.cols()>>2);
  }

  Optimizer::~Optimizer() {
  }

  Eigen::VectorXi Optimizer::OptimizeWindow(int j, int i) {
    Eigen::MatrixXf a(matrix_rows_, matrix_cols_);
    Eigen::VectorXf red(matrix_rows_);
    Eigen::VectorXf green(matrix_rows_);
    Eigen::VectorXf blue(matrix_rows_);
    Eigen::VectorXi result(matrix_cols_);
    int idx, pixel_x, pixel_y;
    float m, distance;
    int o;

    /* Construct the optimization window */
    for (int y = 0; y < window_height_; ++y) {
      for (int x = 0; x < window_width_; ++x) {
        /* Get the position of the pixel we want to fetch */
        idx = y*window_width_ + x;
        pixel_x = util::Clamp(offset_x_*i-1 + x, 0, orig_.cols()-1);
        pixel_y = util::Clamp(offset_y_*j-1 + y, 0, orig_.rows()-1);

        /* Fetch the modulation value and the original color*/
        m = mod_(pixel_y, pixel_x);
        o = orig_(pixel_y, pixel_x);

        /* Fetch the distance weights and construct the matrix */
        distance = kTopLeft[idx];
        a(idx, 0) = distance * (1.0f - m);
        a(idx, 1) = distance * m;
        red(idx) = distance * util::MakeRed(o);
        green(idx) = distance * util::MakeGreen(o);
        blue(idx) = distance * util::MakeBlue(o);

        /* Top right pxel */
        distance = kTopRight[idx];
        a(idx, 2) = distance * (1.0f - m);
        a(idx, 3) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

        /* Bottom left pixel */
        distance = kBottomLeft[idx];
        a(idx, 4) = distance * (1.0f - m);
        a(idx, 5) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

        /* Bottom right pixel */
        distance = kBottomRight[idx];
        a(idx, 6) = distance * (1.0f - m);
        a(idx, 7) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

      }
    }

    /* Solve for the best colors */
    Eigen::JacobiSVD<Eigen::MatrixXf> svd(a, Eigen::ComputeFullU |
                                          Eigen::ComputeFullV);
    Eigen::VectorXf optimal_red = svd.solve(red);
    Eigen::VectorXf optimal_green = svd.solve(green);
    Eigen::VectorXf optimal_blue = svd.solve(blue);

    /* Construct the result vector */
    for (int k = 0; k < result.size(); ++k) {
      result(k) = util::MakeRGBA(static_cast<int>(0xFFFFFFFF),
                                 static_cast<int>(optimal_red(k)),
                                 static_cast<int>(optimal_green(k)),
                                 static_cast<int>(optimal_blue(k)));
    }

    return result;
  }

  void Optimizer::Optimize() {
    for (int j = 0; j < dark_.rows(); j+=2) {
      for (int i = 0; i < dark_.cols(); i+=2) {
        Eigen::VectorXi optimal = OptimizeWindow(j, i);

        /* Set the dark and bright colors */
        dark_(j, i) = optimal(0);
        bright_(j, i) = optimal(1);

        dark_(j, i+1) = optimal(2);
        bright_(j, i+1) = optimal(3);

        dark_(j+1, i) = optimal(4);
        bright_(j+1, i) = optimal(5);

        dark_(j+1, i+1) = optimal(6);
        bright_(j+1, i+1) = optimal(7);
      }
    }
  }
}<commit_msg>Use ThinU and ThinV when computing SVD - this significantly speeds up computation time without impacting the result.<commit_after>//
//  LeastSquaresSolver.cpp
//  pvrtex
//
//  Created by Chirantan Ekbote on 11/14/12.
//
//

#include "../inc/Optimizer.h"

#define ROW(n)	1*n,	2*n,	3*n,	4*n,	3*n,	2*n,	1*n

namespace pvrtex {
  // Optimization window information
  const int Optimizer::window_width_ = 11;
  const int Optimizer::window_height_ = 11;
  const int Optimizer::matrix_rows_ = 121;
  const int Optimizer::matrix_cols_ = 8;
  const int Optimizer::offset_x_ = 4;
  const int Optimizer::offset_y_ = 4;

  // Weight matrices
  const float Optimizer::kTopLeft[] =
  {
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.25f), 0, 0, 0, 0,		// 4/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0
  };
  const float Optimizer::kTopRight[] =
  {
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.25f),		// 4/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0
  };
  const float Optimizer::kBottomLeft[] =
  {
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.25f), 0, 0, 0, 0,		// 4/16
    ROW(0.1875f), 0, 0, 0, 0,	// 3/16
    ROW(0.125f), 0, 0, 0, 0,	// 2/16
    ROW(0.0625f), 0, 0, 0, 0,	// 1/16
  };
  const float Optimizer::kBottomRight[] =
  {
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    ROW(0), 0, 0, 0, 0,
    0, 0, 0, 0, ROW(0.0625f),	// 1/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.25f),		// 4/16
    0, 0, 0, 0, ROW(0.1875f),	// 3/16
    0, 0, 0, 0, ROW(0.125f),	// 2/16
    0, 0, 0, 0, ROW(0.0625f)	// 1/16
  };

  Optimizer::Optimizer(Eigen::MatrixXi o, Eigen::MatrixXf m) :
  orig_(o),
  mod_(m),
  solv_(SVD)
  {
    dark_ = Eigen::MatrixXi(o.rows()>>2, o.cols()>>2);
    bright_ = Eigen::MatrixXi(o.rows()>>2, o.cols()>>2);
  }

  Optimizer::Optimizer(Eigen::MatrixXi o, Eigen::MatrixXf m, SOLVER s) :
  orig_(o),
  mod_(m),
  solv_(s)
  {
    dark_(o.rows()>>2, o.cols()>>2);
    bright_(o.rows()>>2, o.cols()>>2);
  }

  Optimizer::~Optimizer() {
  }

  Eigen::VectorXi Optimizer::OptimizeWindow(int j, int i) {
    Eigen::MatrixXf a(matrix_rows_, matrix_cols_);
    Eigen::VectorXf red(matrix_rows_);
    Eigen::VectorXf green(matrix_rows_);
    Eigen::VectorXf blue(matrix_rows_);
    Eigen::VectorXi result(matrix_cols_);
    int idx, pixel_x, pixel_y;
    float m, distance;
    int o;

    /* Construct the optimization window */
    for (int y = 0; y < window_height_; ++y) {
      for (int x = 0; x < window_width_; ++x) {
        /* Get the position of the pixel we want to fetch */
        idx = y*window_width_ + x;
        pixel_x = util::Clamp(offset_x_*i-1 + x, 0, orig_.cols()-1);
        pixel_y = util::Clamp(offset_y_*j-1 + y, 0, orig_.rows()-1);

        /* Fetch the modulation value and the original color*/
        m = mod_(pixel_y, pixel_x);
        o = orig_(pixel_y, pixel_x);

        /* Fetch the distance weights and construct the matrix */
        distance = kTopLeft[idx];
        a(idx, 0) = distance * (1.0f - m);
        a(idx, 1) = distance * m;
        red(idx) = distance * util::MakeRed(o);
        green(idx) = distance * util::MakeGreen(o);
        blue(idx) = distance * util::MakeBlue(o);

        /* Top right pxel */
        distance = kTopRight[idx];
        a(idx, 2) = distance * (1.0f - m);
        a(idx, 3) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

        /* Bottom left pixel */
        distance = kBottomLeft[idx];
        a(idx, 4) = distance * (1.0f - m);
        a(idx, 5) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

        /* Bottom right pixel */
        distance = kBottomRight[idx];
        a(idx, 6) = distance * (1.0f - m);
        a(idx, 7) = distance * m;
        red(idx) += distance * util::MakeRed(o);
        green(idx) += distance * util::MakeGreen(o);
        blue(idx) += distance * util::MakeBlue(o);

      }
    }

    /* Solve for the best colors */
    Eigen::JacobiSVD<Eigen::MatrixXf> svd(a, Eigen::ComputeThinU |
                                          Eigen::ComputeThinV);
    Eigen::VectorXf optimal_red = svd.solve(red);
    Eigen::VectorXf optimal_green = svd.solve(green);
    Eigen::VectorXf optimal_blue = svd.solve(blue);

    /* Construct the result vector */
    for (int k = 0; k < result.size(); ++k) {
      result(k) = util::MakeRGBA(static_cast<int>(0xFFFFFFFF),
                                 static_cast<int>(optimal_red(k)),
                                 static_cast<int>(optimal_green(k)),
                                 static_cast<int>(optimal_blue(k)));
    }

    return result;
  }

  void Optimizer::Optimize() {
    for (int j = 0; j < dark_.rows(); j+=2) {
      for (int i = 0; i < dark_.cols(); i+=2) {
        Eigen::VectorXi optimal = OptimizeWindow(j, i);

        /* Set the dark and bright colors */
        dark_(j, i) = optimal(0);
        bright_(j, i) = optimal(1);

        dark_(j, i+1) = optimal(2);
        bright_(j, i+1) = optimal(3);

        dark_(j+1, i) = optimal(4);
        bright_(j+1, i) = optimal(5);

        dark_(j+1, i+1) = optimal(6);
        bright_(j+1, i+1) = optimal(7);
      }
    }
  }
}<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a deformable tire (i.e. modeled with an FEA mesh)
//
// =============================================================================

#include "chrono_vehicle/wheeled_vehicle/tire/ChDeformableTire.h"

namespace chrono {
namespace vehicle {

using namespace chrono::fea;

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChDeformableTire::ChDeformableTire(const std::string& name)
    : ChTire(name),
      m_pressure_enabled(true),
      m_contact_enabled(true),
      m_connection_enabled(true),
      m_contact_type(NODE_CLOUD),
      m_contact_node_radius(0.001),
      m_contact_face_thickness(0.0),
      m_use_mat_props(true),
      m_young_modulus(2e5f),
      m_poisson_ratio(0.3f),
      m_friction(0.6f),
      m_restitution(0.1f),
      m_kn(2e5),
      m_kt(2e5),
      m_gn(40),
      m_gt(20),
      m_pressure(-1) {}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDeformableTire::SetContactMaterialProperties(float young_modulus,
                                                    float poisson_ratio) {
    m_use_mat_props = true;

    m_young_modulus = young_modulus;
    m_poisson_ratio = poisson_ratio;
}

void ChDeformableTire::SetContactMaterialCoefficients(float kn, float gn, float kt, float gt) {
    m_use_mat_props = false;

    m_kn = kn;
    m_gn = gn;
    m_kt = kt;
    m_gt = gt;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDeformableTire::Initialize(std::shared_ptr<ChBody> wheel, VehicleSide side) {
    ChTire::Initialize(wheel, side);

    ChSystemDEM* system = dynamic_cast<ChSystemDEM*>(wheel->GetSystem());
    assert(system);

    // Create the tire mesh
    m_mesh = std::make_shared<ChMesh>();
    system->Add(m_mesh);

    // Create the FEA nodes and elements
    CreateMesh(*(wheel.get()), side);

    // Create a load container
    m_load_container = std::make_shared<ChLoadContainer>();
    system->Add(m_load_container);

    // Enable tire pressure
    if (m_pressure_enabled) {
        // If pressure was not explicitly specified, fall back to the default value.
        if (m_pressure < 0)
            m_pressure = GetDefaultPressure();

        // Let the derived class create the pressure load and add it to the load container.
        CreatePressureLoad();
    }

    // Create the contact material
    m_contact_mat = std::make_shared<ChMaterialSurfaceDEM>();
    if (m_use_mat_props) {
        m_contact_mat->SetYoungModulus(m_young_modulus);
        m_contact_mat->SetFriction(m_friction);
        m_contact_mat->SetRestitution(m_restitution);
        m_contact_mat->SetPoissonRatio(m_poisson_ratio);

        system->UseMaterialProperties(true);
    } else {
        m_contact_mat->SetKn(m_kn);
        m_contact_mat->SetGn(m_gn);
        m_contact_mat->SetKt(m_kt);
        m_contact_mat->SetGt(m_gt);

        system->UseMaterialProperties(false);
    }

    // Enable tire contact
    if (m_contact_enabled) {
        // Let the derived class create the contact surface and add it to the mesh.
        CreateContactSurface();
    }

    // Enable tire connection to rim
    if (m_connection_enabled) {
        // Let the derived class create the constraints and add them to the system.
        CreateRimConnections(wheel);
    }

    // Attach mesh visualization (with default settings)
    m_visualization = std::make_shared<ChVisualizationFEAmesh>(*(m_mesh.get()));
    m_visualization->SetFEMdataType(ChVisualizationFEAmesh::E_PLOT_NODE_SPEED_NORM);
    m_visualization->SetColorscaleMinMax(0.0, 1);
    m_visualization->SetSmoothFaces(true);
    m_mesh->AddAsset(m_visualization);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
std::shared_ptr<ChContactSurface> ChDeformableTire::GetContactSurface() const {
    if (m_contact_enabled) {
        return m_mesh->GetContactSurface(0);
    }

    std::shared_ptr<ChContactSurface> empty;
    return empty;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
double ChDeformableTire::GetMass() const {
    double mass;
    ChVector<> com;
    ChMatrix33<> inertia;

    m_mesh->ComputeMassProperties(mass, com, inertia);
    return mass;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
TireForce ChDeformableTire::GetTireForce(bool cosim) const {
    TireForce tire_force;
    tire_force.force = ChVector<>(0, 0, 0);
    tire_force.point = ChVector<>(0, 0, 0);
    tire_force.moment = ChVector<>(0, 0, 0);

    // If the tire is simulated together with the associated vehicle, return zero
    // force and moment. In this case, the tire forces are implicitly applied to
    // the wheel body through the tire-wheel connections.
    // Also return zero forces if the tire is not connected to the wheel.
    if (!cosim || m_connections.size() == 0) {
        return tire_force;
    }

    // If the tire is co-simulated, calculate and return the resultant of all reaction
    // forces and torques in the tire-wheel connections as applied to the wheel body
    // center of mass.  These encapsulate the tire-terrain interaction forces and the
    // inertia of the tire itself.
    auto body_frame = m_connections[0]->GetConstrainedBodyFrame();
    tire_force.point = body_frame->GetPos();

    ChVector<> force;
    ChVector<> moment;
    for (size_t ic = 0; ic < m_connections.size(); ic++) {
        ChCoordsys<> csys = m_connections[ic]->GetLinkAbsoluteCoords();
        ChVector<> react = csys.TransformDirectionLocalToParent(m_connections[ic]->GetReactionOnBody());
        body_frame->To_abs_forcetorque(react, csys.pos, false, force, moment);
        tire_force.force += force;
        tire_force.moment += moment;
    }

    for (size_t ic = 0; ic < m_connectionsD.size(); ic++) {
        ChCoordsys<> csys = m_connectionsD[ic]->GetLinkAbsoluteCoords();
        ChVector<> react = csys.TransformDirectionLocalToParent(m_connectionsD[ic]->GetReactionOnBody());
        body_frame->To_abs_torque(react, false, moment);
        tire_force.moment += moment;
    }

    return tire_force;
}

}  // end namespace vehicle
}  // end namespace chrono
<commit_msg>Additional fix to the issue of setting coefficient of friction for a deformable tire<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for a deformable tire (i.e. modeled with an FEA mesh)
//
// =============================================================================

#include "chrono_vehicle/wheeled_vehicle/tire/ChDeformableTire.h"

namespace chrono {
namespace vehicle {

using namespace chrono::fea;

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChDeformableTire::ChDeformableTire(const std::string& name)
    : ChTire(name),
      m_pressure_enabled(true),
      m_contact_enabled(true),
      m_connection_enabled(true),
      m_contact_type(NODE_CLOUD),
      m_contact_node_radius(0.001),
      m_contact_face_thickness(0.0),
      m_use_mat_props(true),
      m_young_modulus(2e5f),
      m_poisson_ratio(0.3f),
      m_friction(0.6f),
      m_restitution(0.1f),
      m_kn(2e5),
      m_kt(2e5),
      m_gn(40),
      m_gt(20),
      m_pressure(-1) {}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDeformableTire::SetContactMaterialProperties(float young_modulus,
                                                    float poisson_ratio) {
    m_use_mat_props = true;

    m_young_modulus = young_modulus;
    m_poisson_ratio = poisson_ratio;
}

void ChDeformableTire::SetContactMaterialCoefficients(float kn, float gn, float kt, float gt) {
    m_use_mat_props = false;

    m_kn = kn;
    m_gn = gn;
    m_kt = kt;
    m_gt = gt;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDeformableTire::Initialize(std::shared_ptr<ChBody> wheel, VehicleSide side) {
    ChTire::Initialize(wheel, side);

    ChSystemDEM* system = dynamic_cast<ChSystemDEM*>(wheel->GetSystem());
    assert(system);

    // Create the tire mesh
    m_mesh = std::make_shared<ChMesh>();
    system->Add(m_mesh);

    // Create the FEA nodes and elements
    CreateMesh(*(wheel.get()), side);

    // Create a load container
    m_load_container = std::make_shared<ChLoadContainer>();
    system->Add(m_load_container);

    // Enable tire pressure
    if (m_pressure_enabled) {
        // If pressure was not explicitly specified, fall back to the default value.
        if (m_pressure < 0)
            m_pressure = GetDefaultPressure();

        // Let the derived class create the pressure load and add it to the load container.
        CreatePressureLoad();
    }

    // Create the contact material
    m_contact_mat = std::make_shared<ChMaterialSurfaceDEM>();
    m_contact_mat->SetFriction(m_friction);
    m_contact_mat->SetRestitution(m_restitution);

    if (m_use_mat_props) {
        m_contact_mat->SetYoungModulus(m_young_modulus);
        m_contact_mat->SetPoissonRatio(m_poisson_ratio);

        system->UseMaterialProperties(true);
    } else {
        m_contact_mat->SetKn(m_kn);
        m_contact_mat->SetGn(m_gn);
        m_contact_mat->SetKt(m_kt);
        m_contact_mat->SetGt(m_gt);

        system->UseMaterialProperties(false);
    }

    // Enable tire contact
    if (m_contact_enabled) {
        // Let the derived class create the contact surface and add it to the mesh.
        CreateContactSurface();
    }

    // Enable tire connection to rim
    if (m_connection_enabled) {
        // Let the derived class create the constraints and add them to the system.
        CreateRimConnections(wheel);
    }

    // Attach mesh visualization (with default settings)
    m_visualization = std::make_shared<ChVisualizationFEAmesh>(*(m_mesh.get()));
    m_visualization->SetFEMdataType(ChVisualizationFEAmesh::E_PLOT_NODE_SPEED_NORM);
    m_visualization->SetColorscaleMinMax(0.0, 1);
    m_visualization->SetSmoothFaces(true);
    m_mesh->AddAsset(m_visualization);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
std::shared_ptr<ChContactSurface> ChDeformableTire::GetContactSurface() const {
    if (m_contact_enabled) {
        return m_mesh->GetContactSurface(0);
    }

    std::shared_ptr<ChContactSurface> empty;
    return empty;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
double ChDeformableTire::GetMass() const {
    double mass;
    ChVector<> com;
    ChMatrix33<> inertia;

    m_mesh->ComputeMassProperties(mass, com, inertia);
    return mass;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
TireForce ChDeformableTire::GetTireForce(bool cosim) const {
    TireForce tire_force;
    tire_force.force = ChVector<>(0, 0, 0);
    tire_force.point = ChVector<>(0, 0, 0);
    tire_force.moment = ChVector<>(0, 0, 0);

    // If the tire is simulated together with the associated vehicle, return zero
    // force and moment. In this case, the tire forces are implicitly applied to
    // the wheel body through the tire-wheel connections.
    // Also return zero forces if the tire is not connected to the wheel.
    if (!cosim || m_connections.size() == 0) {
        return tire_force;
    }

    // If the tire is co-simulated, calculate and return the resultant of all reaction
    // forces and torques in the tire-wheel connections as applied to the wheel body
    // center of mass.  These encapsulate the tire-terrain interaction forces and the
    // inertia of the tire itself.
    auto body_frame = m_connections[0]->GetConstrainedBodyFrame();
    tire_force.point = body_frame->GetPos();

    ChVector<> force;
    ChVector<> moment;
    for (size_t ic = 0; ic < m_connections.size(); ic++) {
        ChCoordsys<> csys = m_connections[ic]->GetLinkAbsoluteCoords();
        ChVector<> react = csys.TransformDirectionLocalToParent(m_connections[ic]->GetReactionOnBody());
        body_frame->To_abs_forcetorque(react, csys.pos, false, force, moment);
        tire_force.force += force;
        tire_force.moment += moment;
    }

    for (size_t ic = 0; ic < m_connectionsD.size(); ic++) {
        ChCoordsys<> csys = m_connectionsD[ic]->GetLinkAbsoluteCoords();
        ChVector<> react = csys.TransformDirectionLocalToParent(m_connectionsD[ic]->GetReactionOnBody());
        body_frame->To_abs_torque(react, false, moment);
        tire_force.moment += moment;
    }

    return tire_force;
}

}  // end namespace vehicle
}  // end namespace chrono
<|endoftext|>


<commit_before>#include "renderer.h"

Renderer::Renderer()
{
    //-----------------------------------------------------
    // Glew setup
    //-----------------------------------------------------
    glewExperimental = GL_TRUE;
    glewInit();

    //Create programs
    create_program("shaders/triangles.vert","shaders/triangles.frag","triangles");

}

void Renderer::create_program(std::string vertex_path, std::string fragment_path ,std::string program_name){

    // Create and compile the vertex shader ------------------------------------------
    std::string vertex_shader_source = read_shader_file(vertex_path);
    int vertex_shader_source_length = vertex_shader_source.length();
    const char *vertex_shader_source_cstr = vertex_shader_source.c_str();

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertex_shader_source_cstr, &vertex_shader_source_length);
    glCompileShader(vertexShader);
    test_shader_compilation(vertexShader);

    shaders.push_back(vertexShader);
    //--------------------------------------------------------------------------------

    // Create and compile the fragment shader ----------------------------------------
    std::string fragment_shader_source = read_shader_file(fragment_path);
    int fragment_shader_source_length = fragment_shader_source.length();
    const char *fragment_shader_source_cstr = fragment_shader_source.c_str();

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragment_shader_source_cstr, &fragment_shader_source_length);
    glCompileShader(fragmentShader);
    test_shader_compilation(fragmentShader);

    shaders.push_back(fragmentShader);
    //--------------------------------------------------------------------------------

    // Link the vertex and fragment shader into a shader program----------------------
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);

    glUseProgram(shaderProgram);

    GLint uni_screen_resolution = glGetUniformLocation(shaderProgram, "screen_resolution");
    glUniform2f(uni_screen_resolution,SCREEN_RESOLUTION_X,SCREEN_RESOLUTION_Y);

    programs.push_back(shaderProgram);
    programs_map.insert(std::pair<std::string,GLuint>(program_name,shaderProgram));
    //--------------------------------------------------------------------------------
}

void Renderer::display_enemies(){

    GLuint current_program = programs_map["triangles"];
    glUseProgram(current_program);

    //TEMPORARY CODE TO VERIFY THAT EVERYTHING STILL WORKS
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    // Create Vertex Array Object

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);

    std::vector<GLfloat> vertices { {    800 , 600,
                                         900 , 700,
                                         1280 , 600,
                                         0    , 0,
                                         100  , 100,
                                         200  , 0
                                  } };

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*vertices.size(), vertices.data() , GL_STATIC_DRAW);

    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(programs_map["triangles"], "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    // Draw a triangle from the 3 vertices
    glDrawArrays(GL_TRIANGLES, 0, vertices.size()/2 );

    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
}

void Renderer::test_shader_compilation(GLuint shader){
    GLint status;

    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if(status != GL_TRUE){

        char buffer[512];
        glGetShaderInfoLog(shader, 512, NULL, buffer);
        std::cout << buffer << std::endl;

        throw std::runtime_error("Fragment shader compilation failed!");
    }
}

Renderer::~Renderer(){

    for(auto program:programs){
        glDeleteProgram(program);
    }

    for(auto shader:shaders){
        glDeleteShader(shader);
    }

    for(auto &buffer:buffers){
        glDeleteBuffers(1, &buffer);
    }

    for(auto &vertex_array:vertex_arrays){
        glDeleteVertexArrays(1,&vertex_array);
    }

}

void Renderer::clear(){
    // Clear the screen to black
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}
<commit_msg>Fix shader paths<commit_after>#include "renderer.h"

Renderer::Renderer()
{
    //-----------------------------------------------------
    // Glew setup
    //-----------------------------------------------------
    glewExperimental = GL_TRUE;
    glewInit();

    //Create programs
    create_program("../shaders/triangles.vert","../shaders/triangles.frag","triangles");

}

void Renderer::create_program(std::string vertex_path, std::string fragment_path ,std::string program_name){

    // Create and compile the vertex shader ------------------------------------------
    std::string vertex_shader_source = read_shader_file(vertex_path);
    int vertex_shader_source_length = vertex_shader_source.length();
    const char *vertex_shader_source_cstr = vertex_shader_source.c_str();

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertex_shader_source_cstr, &vertex_shader_source_length);
    glCompileShader(vertexShader);
    test_shader_compilation(vertexShader);

    shaders.push_back(vertexShader);
    //--------------------------------------------------------------------------------

    // Create and compile the fragment shader ----------------------------------------
    std::string fragment_shader_source = read_shader_file(fragment_path);
    int fragment_shader_source_length = fragment_shader_source.length();
    const char *fragment_shader_source_cstr = fragment_shader_source.c_str();

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragment_shader_source_cstr, &fragment_shader_source_length);
    glCompileShader(fragmentShader);
    test_shader_compilation(fragmentShader);

    shaders.push_back(fragmentShader);
    //--------------------------------------------------------------------------------

    // Link the vertex and fragment shader into a shader program----------------------
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);

    glUseProgram(shaderProgram);

    GLint uni_screen_resolution = glGetUniformLocation(shaderProgram, "screen_resolution");
    glUniform2f(uni_screen_resolution,SCREEN_RESOLUTION_X,SCREEN_RESOLUTION_Y);

    programs.push_back(shaderProgram);
    programs_map.insert(std::pair<std::string,GLuint>(program_name,shaderProgram));
    //--------------------------------------------------------------------------------
}

void Renderer::display_enemies(){

    GLuint current_program = programs_map["triangles"];
    glUseProgram(current_program);

    //TEMPORARY CODE TO VERIFY THAT EVERYTHING STILL WORKS
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    // Create Vertex Array Object

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);

    std::vector<GLfloat> vertices { {    800 , 600,
                                         900 , 700,
                                         1280 , 600,
                                         0    , 0,
                                         100  , 100,
                                         200  , 0
                                  } };

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0])*vertices.size(), vertices.data() , GL_STATIC_DRAW);

    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(programs_map["triangles"], "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);

    // Draw a triangle from the 3 vertices
    glDrawArrays(GL_TRIANGLES, 0, vertices.size()/2 );

    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
    //--------------------------------------------------------------------------------------------------
}

void Renderer::test_shader_compilation(GLuint shader){
    GLint status;

    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if(status != GL_TRUE){

        char buffer[512];
        glGetShaderInfoLog(shader, 512, NULL, buffer);
        std::cout << buffer << std::endl;

        throw std::runtime_error("Fragment shader compilation failed!");
    }
}

Renderer::~Renderer(){

    for(auto program:programs){
        glDeleteProgram(program);
    }

    for(auto shader:shaders){
        glDeleteShader(shader);
    }

    for(auto &buffer:buffers){
        glDeleteBuffers(1, &buffer);
    }

    for(auto &vertex_array:vertex_arrays){
        glDeleteVertexArrays(1,&vertex_array);
    }

}

void Renderer::clear(){
    // Clear the screen to black
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
}
<|endoftext|>


<commit_before>//
//  android_sound.cc
//  SharkSound
//
//  Created by Jon Sharkey on 2013-06-25.
//  Copyright 2013 Sharkable. All rights reserved.
//

#include "sharksound/android/android_sound.h"

#include "sharksound/android/android_sound_instance.h"

using namespace SharkSound;
using std::string;

AndroidSound::AndroidSound(SoundController *sound_controller)
    : Sound(sound_controller),
      loop_instance_(NULL),
      sl_engine_itf_(NULL) {
}

AndroidSound::~AndroidSound() {
  for (auto i = sound_instances_.begin(); i != sound_instances_.end(); i++) {
    delete *i;
  }
}

bool AndroidSound::Init(AAssetManager *asset_manager, SLEngineItf sl_engine_itf,
                        SLDataSink sl_data_sink, string filename) {
  sl_engine_itf_ = sl_engine_itf;
  sl_data_sink_ = sl_data_sink;

  assert(NULL != asset_manager);
  AAsset* asset = AAssetManager_open(asset_manager, filename.c_str(), AASSET_MODE_UNKNOWN);
  // the asset might not be found
  assert(NULL != asset);

  // open asset as file descriptor
  off_t start, length;
  int fd = AAsset_openFileDescriptor(asset, &start, &length);
  assert(0 <= fd);
  AAsset_close(asset);

  // configure audio source
  sl_data_locator_ = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
  sl_format_mime_ = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
  sl_audio_source_ = {&sl_data_locator_, &sl_format_mime_};

  AndroidSoundInstance *instance = CreateNewInstance();
  if (instance) {
    sound_instances_.push_back(instance);
  }

  return true;
}

#pragma mark - Sound

bool AndroidSound::Play(float volume, float position) {
  AndroidSoundInstance *instance = NULL;
  for (auto i = sound_instances_.begin(); i != sound_instances_.end(); i++) {
    if (!(*i)->is_busy()) {
      instance = *i;
      break;
    }
  }
  if (instance == NULL) {
    instance = CreateNewInstance();
    if (instance) {
      sound_instances_.push_back(instance);
    }
  }
  if (instance) {
    instance->Play(volume, position);
    return true;
  }
  return false;
}

bool AndroidSound::PlayLoop() {
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return false;
  }
  loop_instance_->PlayLoop();
}

bool AndroidSound::StopLoop() {
  if (!loop_instance_) {
    return false;
  }
  loop_instance_->Stop();
  return true;
}

void AndroidSound::RewindLoop() {
  if (!loop_instance_) {
    return;
  }
  loop_instance_->Rewind();
}

void AndroidSound::SetLoopVolume(float volume) {
  loop_volume_ = volume;
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return;
  }
  loop_instance_->SetVolume(volume);
}

float AndroidSound::LoopVolume() {
  return loop_volume_;
}

void AndroidSound::SetLoopPosition(float position) {
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return;
  }
  loop_instance_->SetPosition(position);
}

bool AndroidSound::IsLoopPlaying() {
  return (!loop_instance_ && !loop_instance_->is_busy());
}

#pragma mark - private

AndroidSoundInstance * AndroidSound::CreateNewInstance() {
  AndroidSoundInstance *instance = new AndroidSoundInstance();
  if (instance->Init(sl_engine_itf_, sl_audio_source_, sl_data_sink_)) {
    return instance;
  }
  delete instance;
  return NULL;
}
<commit_msg>[Android] LoopVolume is affected by GlobalVolume. Default LoopVolume to 1.0. Respect SoundOn(false).<commit_after>//
//  android_sound.cc
//  SharkSound
//
//  Created by Jon Sharkey on 2013-06-25.
//  Copyright 2013 Sharkable. All rights reserved.
//

#include "sharksound/android/android_sound.h"

#include "sharksound/android/android_sound_instance.h"

using namespace SharkSound;
using std::string;

AndroidSound::AndroidSound(SoundController *sound_controller)
    : Sound(sound_controller),
      loop_instance_(NULL),
      loop_volume_(1.f),
      sl_engine_itf_(NULL) {
}

AndroidSound::~AndroidSound() {
  for (auto i = sound_instances_.begin(); i != sound_instances_.end(); i++) {
    delete *i;
  }
}

bool AndroidSound::Init(AAssetManager *asset_manager, SLEngineItf sl_engine_itf,
                        SLDataSink sl_data_sink, string filename) {
  sl_engine_itf_ = sl_engine_itf;
  sl_data_sink_ = sl_data_sink;

  assert(NULL != asset_manager);
  AAsset* asset = AAssetManager_open(asset_manager, filename.c_str(), AASSET_MODE_UNKNOWN);
  // the asset might not be found
  assert(NULL != asset);

  // open asset as file descriptor
  off_t start, length;
  int fd = AAsset_openFileDescriptor(asset, &start, &length);
  assert(0 <= fd);
  AAsset_close(asset);

  // configure audio source
  sl_data_locator_ = {SL_DATALOCATOR_ANDROIDFD, fd, start, length};
  sl_format_mime_ = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
  sl_audio_source_ = {&sl_data_locator_, &sl_format_mime_};

  AndroidSoundInstance *instance = CreateNewInstance();
  if (instance) {
    sound_instances_.push_back(instance);
  }

  return true;
}

#pragma mark - Sound

bool AndroidSound::Play(float volume, float position) {
  if (!on_) {
    return false;
  }
  AndroidSoundInstance *instance = NULL;
  for (auto i = sound_instances_.begin(); i != sound_instances_.end(); i++) {
    if (!(*i)->is_busy()) {
      instance = *i;
      break;
    }
  }
  if (instance == NULL) {
    instance = CreateNewInstance();
    if (instance) {
      sound_instances_.push_back(instance);
    }
  }
  if (instance) {
    instance->Play(volume * global_volume_, position);
    return true;
  }
  return false;
}

bool AndroidSound::PlayLoop() {
  if (!on_) {
    return false;
  }
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return false;
  }
  loop_instance_->PlayLoop();
}

bool AndroidSound::StopLoop() {
  if (!loop_instance_) {
    return false;
  }
  loop_instance_->Stop();
  return true;
}

void AndroidSound::RewindLoop() {
  if (!loop_instance_) {
    return;
  }
  loop_instance_->Rewind();
}

void AndroidSound::SetLoopVolume(float volume) {
  loop_volume_ = volume;
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return;
  }
  loop_instance_->SetVolume(volume * global_volume_);
}

float AndroidSound::LoopVolume() {
  return loop_volume_;
}

void AndroidSound::SetLoopPosition(float position) {
  if (!loop_instance_) {
    loop_instance_ = CreateNewInstance();
  }
  if (!loop_instance_) {
    return;
  }
  loop_instance_->SetPosition(position);
}

bool AndroidSound::IsLoopPlaying() {
  return (!loop_instance_ && !loop_instance_->is_busy());
}

#pragma mark - private

AndroidSoundInstance * AndroidSound::CreateNewInstance() {
  AndroidSoundInstance *instance = new AndroidSoundInstance();
  if (instance->Init(sl_engine_itf_, sl_audio_source_, sl_data_sink_)) {
    return instance;
  }
  delete instance;
  return NULL;
}
<|endoftext|>


<commit_before>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include <iostream>
#include <sstream>
#include "frame_selector.h"
#include "image_view.h"
#include <vector>
#include "../ProcessControl/controller.h"

using namespace std;

int main(int argc, const char* argv[]) {

    if (argc > 3 || argc == 1){

        cerr << "Usage:  " << " FULL_PATH_TO_HDF5_FILE (optional: image index)" << endl;
        return -1;

    }

    if(argc == 2){

        Controller controller;
        controller.PlayHDFAsVideo(argv[1]);

    } else if(argc == 3){

        FrameSelector pipeline(argv[1]);
        // read one image
        unsigned int index = 0;
        stringstream string_index(argv[2]);
        string_index >> index;
        Image result_image = pipeline.ReadImage(index);

        ImageView image_viewer;
        image_viewer.ShowImage(result_image, 0);
    }

    return 0;
}
<commit_msg>adapted main to use FrameSelectorFactory<commit_after>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include <iostream>
#include <sstream>
#include "hdf5_frame_selector.h"
#include "frame_selector_factory.h"
#include "image_view.h"
#include <vector>
#include "../ProcessControl/controller.h"

using namespace std;

int main(int argc, const char* argv[]) {

    if (argc > 3 || argc == 1){

        cerr << "Usage:  " << " FULL_PATH_TO_HDF5_FILE (optional: image index)" << endl;
        return -1;

    }

    if(argc == 2){

        Controller controller;
        controller.PlayHDFAsVideo(argv[1]);

    } else if(argc == 3){

        FrameSelectorFactory frame_selector_factory(argv[1]);
        FrameSelector* pipeline = frame_selector_factory.GetFrameSelector();
        // read one image
        unsigned int index = 0;
        stringstream string_index(argv[2]);
        string_index >> index;
        Image result_image = pipeline->ReadImage(index);

        ImageView image_viewer;
        image_viewer.ShowImage(result_image, 0);
    }

    return 0;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////////////////////////////
// Part of Injectable Generic Camera System
// Copyright(c) 2017, Frans Bouma
// All rights reserved.
// https://github.com/FransBouma/InjectableGenericCameraSystem
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met :
//
//  * Redistributions of source code must retain the above copyright notice, this
//	  list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and / or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Camera.h"
#include "Defaults.h"
#include "GameConstants.h"
#include "Globals.h"

using namespace DirectX;

namespace IGCS
{
	Camera::Camera() : _yaw(0), _pitch(0), _roll(0), _movementOccurred(false), _lookDirectionInverter(1.0f), _direction(XMFLOAT3(0.0f, 0.0f, 0.0f))
	{
	}

	Camera::~Camera(void)
	{
	}

	XMVECTOR Camera::calculateLookQuaternion()
	{
		// for the camera 3x3 matrix, it uses X right, Z up and Y into the screen.
		XMVECTOR xQ = XMQuaternionRotationNormal(XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f), _pitch);
		XMVECTOR yQ = XMQuaternionRotationNormal(XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f), _roll);			// y into the screen
		XMVECTOR zQ = XMQuaternionRotationNormal(XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f), _yaw);

		XMVECTOR tmpQ = XMQuaternionMultiply(xQ, zQ);
		XMVECTOR qToReturn = XMQuaternionMultiply(yQ, tmpQ);
		XMQuaternionNormalize(qToReturn);
		return qToReturn;
	}

	void Camera::resetMovement()
	{
		_movementOccurred = false;
		_direction.x = 0.0f;
		_direction.y = 0.0f;
		_direction.z = 0.0f;
	}

	void Camera::resetAngles()
	{
		setPitch(INITIAL_PITCH_RADIANS);
		setRoll(INITIAL_ROLL_RADIANS);
		setYaw(INITIAL_YAW_RADIANS);
	}

	XMFLOAT3 Camera::calculateNewCoords(const XMFLOAT3 currentCoords, const XMVECTOR lookQ)
	{
		XMFLOAT3 toReturn;
		toReturn.x = currentCoords.x;
		toReturn.y = currentCoords.y;
		toReturn.z = currentCoords.z;
		if (_movementOccurred)
		{
			XMVECTOR directionAsQ = XMVectorSet(_direction.x, _direction.y, _direction.z, 0.0f);
			XMVECTOR newDirection = XMVector3Rotate(directionAsQ, lookQ);
			toReturn.x += XMVectorGetX(newDirection);
			toReturn.y += XMVectorGetY(newDirection);
			toReturn.z += XMVectorGetZ(newDirection);
		}
		return toReturn;
	}

	void Camera::moveForward(float amount)
	{
		_direction.y += (Globals::instance().settings().movementSpeed * amount);		// z up, y into of the screen.
		_movementOccurred = true;
	}

	void Camera::moveRight(float amount)
	{
		_direction.x += (Globals::instance().settings().movementSpeed * amount);		// x is right
		_movementOccurred = true;
	}

	void Camera::moveUp(float amount)
	{
		_direction.z += (Globals::instance().settings().movementSpeed * amount * Globals::instance().settings().movementUpMultiplier);
		_movementOccurred = true;
	}

	void Camera::yaw(float amount)
	{
		_yaw -= (Globals::instance().settings().rotationSpeed * amount);				// Z is up, so we have to rotate to the left.
		_yaw = clampAngle(_yaw);
	}

	void Camera::pitch(float amount)
	{
		float lookDirectionInverter = _lookDirectionInverter;
		if (Globals::instance().settings().invertY)
		{
			lookDirectionInverter = -lookDirectionInverter;
		}
		_pitch += (Globals::instance().settings().rotationSpeed * amount * lookDirectionInverter);
		_pitch = clampAngle(_pitch);
	}

	void Camera::roll(float amount)
	{
		_roll += (Globals::instance().settings().rotationSpeed * amount);
		_roll = clampAngle(_roll);
	}

	void Camera::setPitch(float angle)
	{
		_pitch = clampAngle(angle);
	}

	void Camera::setYaw(float angle)
	{
		_yaw = clampAngle(angle);
	}

	void Camera::setRoll(float angle)
	{
		_roll = clampAngle(angle);
	}

	// Keep the angle in the range 0 to 360 (2*PI)
	float Camera::clampAngle(float angle) const
	{
		while (angle > XM_2PI)
		{
			angle -= XM_2PI;
		}
		while (angle < 0)
		{
			angle += XM_2PI;
		}
		return angle;
	}
}<commit_msg>Update Camera.cpp<commit_after>////////////////////////////////////////////////////////////////////////////////////////////////////////
// Part of Injectable Generic Camera System
// Copyright(c) 2017, Frans Bouma
// All rights reserved.
// https://github.com/FransBouma/InjectableGenericCameraSystem
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met :
//
//  * Redistributions of source code must retain the above copyright notice, this
//	  list of conditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and / or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Camera.h"
#include "Defaults.h"
#include "GameConstants.h"
#include "Globals.h"
#include "MessageHandler.h"

using namespace DirectX;

namespace IGCS
{
	Camera::Camera() : _yaw(0), _pitch(0), _roll(0), _movementOccurred(false), _lookDirectionInverter(1.0f), _direction(XMFLOAT3(0.0f, 0.0f, 0.0f))
	{
	}

	Camera::~Camera(void)
	{
	}

	XMVECTOR Camera::calculateLookQuaternion()
	{
		// for the camera 3x3 matrix, it uses X right, Z up and Y into the screen.
		XMVECTOR xQ = XMQuaternionRotationNormal(XMVectorSet(1.0f, 0.0f, 0.0f, 1.0f), _pitch);
		XMVECTOR yQ = XMQuaternionRotationNormal(XMVectorSet(0.0f, 1.0f, 0.0f, 1.0f), _roll);			// y into the screen
		XMVECTOR zQ = XMQuaternionRotationNormal(XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f), _yaw);

		XMVECTOR tmpQ = XMQuaternionMultiply(xQ, zQ);
		XMVECTOR qToReturn = XMQuaternionMultiply(yQ, tmpQ);
		XMQuaternionNormalize(qToReturn);
		return qToReturn;
	}

	void Camera::resetMovement()
	{
		_movementOccurred = false;
		_direction.x = 0.0f;
		_direction.y = 0.0f;
		_direction.z = 0.0f;
	}

	void Camera::resetAngles()
	{
		setPitch(INITIAL_PITCH_RADIANS);
		setRoll(INITIAL_ROLL_RADIANS);
		setYaw(INITIAL_YAW_RADIANS);
	}

	XMFLOAT3 Camera::calculateNewCoords(const XMFLOAT3 currentCoords, const XMVECTOR lookQ)
	{
		XMFLOAT3 toReturn;
		toReturn.x = currentCoords.x;
		toReturn.y = currentCoords.y;
		toReturn.z = currentCoords.z;
		if (_movementOccurred)
		{
			XMVECTOR directionAsQ = XMVectorSet(_direction.x, _direction.y, _direction.z, 0.0f);
			XMVECTOR newDirection = XMVector3Rotate(directionAsQ, lookQ);
			toReturn.x += XMVectorGetX(newDirection);
			toReturn.y += XMVectorGetY(newDirection);
			toReturn.z += XMVectorGetZ(newDirection);
		}
		return toReturn;
	}

	void Camera::moveForward(float amount)
	{
		_direction.y += (Globals::instance().settings().movementSpeed * amount);		// z up, y into of the screen.
		_movementOccurred = true;
	}

	void Camera::moveRight(float amount)
	{
		_direction.x += (Globals::instance().settings().movementSpeed * amount);		// x is right
		_movementOccurred = true;
	}

	void Camera::moveUp(float amount)
	{
		_direction.z += (Globals::instance().settings().movementSpeed * amount * Globals::instance().settings().movementUpMultiplier);
		_movementOccurred = true;
	}

	void Camera::yaw(float amount)
	{
		_yaw -= (Globals::instance().settings().rotationSpeed * amount);				// Z is up, so we have to rotate to the left.
		_yaw = clampAngle(_yaw);
	}

	void Camera::pitch(float amount)
	{
		float lookDirectionInverter = _lookDirectionInverter;
		if (Globals::instance().settings().invertY)
		{
			lookDirectionInverter = -lookDirectionInverter;
		}
		_pitch += (Globals::instance().settings().rotationSpeed * amount * lookDirectionInverter);
		_pitch = clampAngle(_pitch);
	}

	void Camera::roll(float amount)
	{
		_roll += (Globals::instance().settings().rotationSpeed * amount);
		_roll = clampAngle(_roll);
	}

	void Camera::setPitch(float angle)
	{
		_pitch = clampAngle(angle);
	}

	void Camera::setYaw(float angle)
	{
		_yaw = clampAngle(angle);
	}

	void Camera::setRoll(float angle)
	{
		_roll = clampAngle(angle);
	}

	// Keep the angle in the range 0 to 360 (2*PI)
	float Camera::clampAngle(float angle) const
	{
		while (angle > XM_2PI)
		{
			angle -= XM_2PI;
		}
		while (angle < 0)
		{
			angle += XM_2PI;
		}
		return angle;
	}
}<|endoftext|>