<commit_before>#include "../include/graph.h"
#include "../include/tournament.h"
#include <vector>
#include <cmath>
#include <set>
#include <cassert>

typedef std::shared_ptr<Tournament> tournament_ptr;

bool check_if_fixable(TournamentGraph& graph, int node)
{
    int wins = 0;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
    }
    if (wins < log2(graph.get_size()))
        return false;
    else
    {
        for (int i=0; i<graph.get_size(); ++i)
        {
            if(i == node)
                continue;
            wins = 0;
            for (int j=0; j<graph.get_size(); ++j)
            {
                if(i == j)
                    continue;
                if(graph.wins(i, j))
                    wins++;
                else
                    break;
            }
            if(wins == graph.get_size() - 1)
                return false;
        }
        return true;
    }
}

bool check_if_case_A(TournamentGraph& graph, int node)
{
    int wins = 0;
    int max_wins_from_losses = 0;
    int wins_from_losses;

    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
        else
        {
            wins_from_losses = 0;
            for (int j=0; j<graph.get_size(); ++j)
            {
                if(i == j)
                    break;
                if(graph.wins(i,j))
                    wins_from_losses++;
            }
            if(wins_from_losses > max_wins_from_losses)
            {
                max_wins_from_losses = wins_from_losses;
            }
        }
    }
    return wins > max_wins_from_losses;
}

tournament_ptr fix_tournament_A(TournamentGraph& graph, int node)
{
    std::set<tournament_ptr> won_tournaments, lost_tournaments;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(node == i)
            continue;
        if(graph.wins(node, i))
            won_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
        else
            lost_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
    }
    std::set<tournament_ptr> new_won_tournaments;
    std::set<tournament_ptr> won_copy(won_tournaments);
    std::set<tournament_ptr> lost_copy(lost_tournaments);

    for(auto lose: lost_copy)
    {
        for(auto win: won_copy)
        {
            if(won_tournaments.count(win) && graph.wins(win->get_winner(),
                                                        lose->get_winner()))
            {
                won_tournaments.erase(win);
                lost_tournaments.erase(lose);
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*win, *lose)));
                break;
            }
        }
    }

    assert(lost_tournaments.size() == 0);
    while(won_tournaments.size() > 1)
    {
        for (auto i = won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==won_tournaments.end())
            {
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, Tournament(&graph, node))));
                break;
            }
            auto compatitor2 = *i;
            new_won_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
    }

    return *won_tournaments.begin();
 }

bool check_if_case_B(TournamentGraph& graph, int node)
{
    int wins = 0;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
    }
    return wins >= graph.get_size() / 2;
}

tournament_ptr fix_tournament_B(TournamentGraph &graph, int node)
{
    std::set<tournament_ptr> won_tournaments, lost_tournaments;
    std::set<tournament_ptr> new_won_tournaments, new_lost_tournaments;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(node == i)
            continue;
        if(graph.wins(node, i))
            won_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
        else
            lost_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
    }
    while(lost_tournaments.size() > 0)
    {
        std::set<tournament_ptr> won_copy(won_tournaments);
        std::set<tournament_ptr> lost_copy(lost_tournaments);

        for(auto lose: lost_copy)
        {
            for(auto win: won_copy)
            {
                if(won_tournaments.count(win) && graph.wins(win->get_winner(),
                                                            lose->get_winner()))
                {
                    won_tournaments.erase(win);
                    lost_tournaments.erase(lose);
                    new_won_tournaments.insert(tournament_ptr(
                        new Tournament(*win, *lose)));
                    break;
                }
            }
        }
        for (auto i=lost_tournaments.begin(); i!=lost_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==lost_tournaments.end())
            {
                auto won_example = *won_tournaments.begin();
                won_tournaments.erase(won_example);
                new_lost_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, *won_example)));
                break;
            }
            auto compatitor2 = *i;
            new_lost_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        for (auto i=won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==won_tournaments.end())
            {
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, Tournament(&graph, node))));
                break;
            }
            auto compatitor2 = *i;
            new_won_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
        lost_tournaments = new_lost_tournaments;
        new_lost_tournaments.clear();
    }

    while(won_tournaments.size() > 1)
    {
        for (auto i = won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            ++i;
            auto compatitor2 = *i;
            new_won_tournaments.insert(
                std::shared_ptr<Tournament>(
                    new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
    }
    return *won_tournaments.begin();
}

void fix_tournament(TournamentGraph& graph, int node)
{
    if(check_if_fixable(graph, node))
    {
        std::shared_ptr<Tournament> tournament;
        printf("Fixable\n");
        if (check_if_case_A(graph, node))
        {
            printf("Case A\n");
            tournament = fix_tournament_A(graph, node);
        }
        else if (check_if_case_B(graph, node))
        {
            printf("Case B\n");
            tournament = fix_tournament_B(graph, node);
        }
        else
        {
            printf("Worst Case");
        }
    }
    else
    {
        printf("Unfixable\n");
    }

}
<commit_msg>Refactor.<commit_after>#include <vector>
#include <cmath>
#include <set>
#include <cassert>

#include "../include/graph.h"
#include "../include/tournament.h"

typedef std::shared_ptr<Tournament> tournament_ptr;

bool check_if_fixable(TournamentGraph& graph, int node)
{
    int wins = 0;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
    }
    if (wins < log2(graph.get_size()))
        return false;
    else
    {
        for (int i=0; i<graph.get_size(); ++i)
        {
            if(i == node)
                continue;
            wins = 0;
            for (int j=0; j<graph.get_size(); ++j)
            {
                if(i == j)
                    continue;
                if(graph.wins(i, j))
                    wins++;
                else
                    break;
            }
            if(wins == graph.get_size() - 1)
                return false;
        }
        return true;
    }
}

bool check_if_case_A(TournamentGraph& graph, int node)
{
    int wins = 0;
    int max_wins_from_losses = 0;
    int wins_from_losses;

    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
        else
        {
            wins_from_losses = 0;
            for (int j=0; j<graph.get_size(); ++j)
            {
                if(i == j)
                    break;
                if(graph.wins(i,j))
                    wins_from_losses++;
            }
            if(wins_from_losses > max_wins_from_losses)
            {
                max_wins_from_losses = wins_from_losses;
            }
        }
    }
    return wins > max_wins_from_losses;
}

tournament_ptr fix_tournament_A(TournamentGraph& graph, int node)
{
    std::set<tournament_ptr> won_tournaments, lost_tournaments;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(node == i)
            continue;
        if(graph.wins(node, i))
            won_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
        else
            lost_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
    }
    std::set<tournament_ptr> new_won_tournaments;
    std::set<tournament_ptr> won_copy(won_tournaments);
    std::set<tournament_ptr> lost_copy(lost_tournaments);

    for(auto lose: lost_copy)
    {
        for(auto win: won_copy)
        {
            if(won_tournaments.count(win) && graph.wins(win->get_winner(),
                                                        lose->get_winner()))
            {
                won_tournaments.erase(win);
                lost_tournaments.erase(lose);
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*win, *lose)));
                break;
            }
        }
    }

    assert(lost_tournaments.size() == 0);
    while(won_tournaments.size() > 1)
    {
        for (auto i = won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==won_tournaments.end())
            {
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, Tournament(&graph, node))));
                break;
            }
            auto compatitor2 = *i;
            new_won_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
    }

    return *won_tournaments.begin();
 }

bool check_if_case_B(TournamentGraph& graph, int node)
{
    int wins = 0;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(i != node && graph.wins(node, i))
            wins++;
    }
    return wins >= graph.get_size() / 2;
}

tournament_ptr fix_tournament_B(TournamentGraph &graph, int node)
{
    std::set<tournament_ptr> won_tournaments, lost_tournaments;
    std::set<tournament_ptr> new_won_tournaments, new_lost_tournaments;
    for (int i=0; i<graph.get_size(); ++i)
    {
        if(node == i)
            continue;
        if(graph.wins(node, i))
            won_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
        else
            lost_tournaments.insert(tournament_ptr(new Tournament(&graph, i)));
    }
    while(lost_tournaments.size() > 0)
    {
        std::set<tournament_ptr> won_copy(won_tournaments);
        std::set<tournament_ptr> lost_copy(lost_tournaments);

        for(auto lose: lost_copy)
        {
            for(auto win: won_copy)
            {
                if(won_tournaments.count(win) && graph.wins(win->get_winner(),
                                                            lose->get_winner()))
                {
                    won_tournaments.erase(win);
                    lost_tournaments.erase(lose);
                    new_won_tournaments.insert(tournament_ptr(
                        new Tournament(*win, *lose)));
                    break;
                }
            }
        }
        for (auto i=lost_tournaments.begin(); i!=lost_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==lost_tournaments.end())
            {
                auto won_example = *won_tournaments.begin();
                won_tournaments.erase(won_example);
                new_lost_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, *won_example)));
                break;
            }
            auto compatitor2 = *i;
            new_lost_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        for (auto i=won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            if (++i==won_tournaments.end())
            {
                new_won_tournaments.insert(tournament_ptr(
                    new Tournament(*compatitor1, Tournament(&graph, node))));
                break;
            }
            auto compatitor2 = *i;
            new_won_tournaments.insert(tournament_ptr(
                new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
        lost_tournaments = new_lost_tournaments;
        new_lost_tournaments.clear();
    }

    while(won_tournaments.size() > 1)
    {
        for (auto i = won_tournaments.begin(); i!=won_tournaments.end(); ++i)
        {
            auto compatitor1 = *i;
            ++i;
            auto compatitor2 = *i;
            new_won_tournaments.insert(
                std::shared_ptr<Tournament>(
                    new Tournament(*compatitor1, *compatitor2)));
        }
        won_tournaments = new_won_tournaments;
        new_won_tournaments.clear();
    }
    return *won_tournaments.begin();
}

void fix_tournament(TournamentGraph& graph, int node)
{
    if(check_if_fixable(graph, node))
    {
        std::shared_ptr<Tournament> tournament;
        printf("Fixable\n");
        if (check_if_case_A(graph, node))
        {
            printf("Case A\n");
            tournament = fix_tournament_A(graph, node);
        }
        else if (check_if_case_B(graph, node))
        {
            printf("Case B\n");
            tournament = fix_tournament_B(graph, node);
        }
        else
        {
            printf("Worst Case");
        }
    }
    else
    {
        printf("Unfixable\n");
    }

}
<|endoftext|>


<commit_before>75dea8f5-4b02-11e5-b4a7-28cfe9171a43<commit_msg>Did ANOTHER thing<commit_after>75ed1e68-4b02-11e5-9fcc-28cfe9171a43<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "CameraHandler.h"
#include "WorldBuildingModule.h"
#include "Quaternion.h"

#include <SceneManager.h>
#include <EC_OgrePlaceable.h>
#include <EC_OgreCamera.h>
#include <EC_OgreMesh.h>
#include <EC_OgreCustomObject.h>

#include <Ogre.h>
#include <QUuid>

#include <QDebug>

namespace WorldBuilding
{
    namespace View
    {
        CameraHandler::CameraHandler(Foundation::Framework *framework, QObject *parent) :
            QObject(parent),
            framework_(framework),
            camera_count_(0),
            pixelData_(0),
            last_dir_(Vector3df::ZERO)
        {
            render_texture_name_ = "EntityViewPortTexture_" + QUuid::createUuid().toString().toStdString();

            Ogre::TexturePtr entity_screenshot = Ogre::TextureManager::getSingleton().createManual(
                render_texture_name_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                Ogre::TEX_TYPE_2D, 1, 1, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET);

            entity_screenshot->getBuffer()->getRenderTarget()->setAutoUpdated(false);
        }

        CameraHandler::~CameraHandler()
        {
            SAFE_DELETE(pixelData_);
        }

        CameraID CameraHandler::CreateCustomCamera()
        {
            Scene::ScenePtr scene = framework_->GetDefaultWorldScene();
            if (!scene)
                return -1;

            Scene::EntityPtr cam_entity = scene->CreateEntity(scene->GetNextFreeId());
            if (!cam_entity.get())
                return -1;

            cam_entity->AddComponent(framework_->GetComponentManager()->CreateComponent(OgreRenderer::EC_OgrePlaceable::TypeNameStatic()));
            cam_entity->AddComponent(framework_->GetComponentManager()->CreateComponent(OgreRenderer::EC_OgreCamera::TypeNameStatic()));

            Foundation::ComponentInterfacePtr component_placable = cam_entity->GetComponent(OgreRenderer::EC_OgrePlaceable::TypeNameStatic());
            OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();

            if (!component_placable.get() || !ec_camera)
                return -1;
            ec_camera->SetPlaceable(component_placable);

            camera_count_++;
            id_to_cam_entity_[camera_count_] = cam_entity.get();

            return camera_count_;
        }

        void CameraHandler::DestroyCamera(CameraID cam_id)
        {
            if (id_to_cam_entity_.contains(cam_id))
                id_to_cam_entity_.remove(cam_id);

            Ogre::TexturePtr entity_viewport_texture = Ogre::TextureManager::getSingleton().getByName(render_texture_name_);
            if (entity_viewport_texture.isNull())
                return;

            Ogre::RenderTexture *render_texture = entity_viewport_texture->getBuffer()->getRenderTarget();
            if (render_texture)
                render_texture->removeAllViewports();
        }

        bool CameraHandler::FocusToEntity(CameraID cam_id, Scene::Entity *entity, Vector3df offset)
        {
            bool focus_completed = false;

            if (!id_to_cam_entity_.contains(cam_id))
                return focus_completed;
            Scene::Entity *cam_entity = id_to_cam_entity_[cam_id];

            // Get placable from both focus entity and our camera id entity
            OgreRenderer::EC_OgrePlaceable *entity_ec_placable = entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
            OgreRenderer::EC_OgrePlaceable *cam_ec_placable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
            OgreRenderer::EC_OgreCamera *cam_ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();

            if (!entity_ec_placable || !cam_ec_placable || !cam_ec_camera)
                return focus_completed;

            OgreRenderer::EC_OgreMesh *entity_mesh = entity->GetComponent<OgreRenderer::EC_OgreMesh>().get();
            OgreRenderer::EC_OgreCustomObject *entity_custom_object = entity->GetComponent<OgreRenderer::EC_OgreCustomObject>().get();

            Vector3df position_vector = entity_ec_placable->GetPosition();
            Vector3df position_offset;
            Vector3df look_at;

            Vector3df bounding_min;
            Vector3df bounding_max;
            Vector3df der_size_vector;
            Ogre::Vector3 derived_scale;

            if (entity_mesh)
            {
                entity_mesh->GetBoundingBox(bounding_min, bounding_max);
                derived_scale = entity_mesh->GetEntity()->getParentNode()->_getDerivedScale();
                der_size_vector = Vector3df(derived_scale.x, derived_scale.y, derived_scale.z) * (bounding_max - bounding_min);

                position_offset = Vector3df(der_size_vector.x, -der_size_vector.y, der_size_vector.y);
                look_at = Vector3df(position_vector.x, position_vector.y, position_vector.z + (position_offset.z/2));
            }
            else if (entity_custom_object)
            {
                entity_custom_object->GetBoundingBox(bounding_min, bounding_max);
                derived_scale = entity_custom_object->GetEntity()->getParentNode()->_getDerivedScale();
                der_size_vector = Vector3df(derived_scale.x, derived_scale.y, derived_scale.z) * (bounding_max - bounding_min);

                float max_distance = 0;
                if (der_size_vector.x > max_distance)
                    max_distance = der_size_vector.x;
                if (der_size_vector.y > max_distance)
                    max_distance = der_size_vector.y;
                if (der_size_vector.z > max_distance)
                    max_distance = der_size_vector.z;

                position_offset = Vector3df(der_size_vector.x, -max_distance, max_distance/4);
                look_at = Vector3df(position_vector.x, position_vector.y, position_vector.z + (position_offset.z/2));
            }
            else
                return focus_completed;

            cam_ec_placable->SetPosition(position_vector + (entity_ec_placable->GetOrientation() * position_offset));
            if (last_dir_ != Vector3df::ZERO)
            {
                //qDebug() << "Testig";
                //cam_ec_placable->SetPosition(cam_ec_placable->GetPosition() + last_dir_);
            }
            cam_ec_placable->LookAt(look_at);

            focus_completed = true;
            return focus_completed;
        }

        void CameraHandler::RotateCamera(Vector3df pivot, CameraID id, qreal x, qreal y)
        {
            if (id_to_cam_entity_.contains(id))
            {
                Scene::Entity *cam_entity = id_to_cam_entity_[id];
                OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();
                OgreRenderer::EC_OgrePlaceable *cam_ec_placable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
                if (!ec_camera || !cam_ec_placable)
                    return;

                Ogre::Camera* cam = ec_camera->GetCamera();
                Vector3df pos = cam_ec_placable->GetPosition();

                Vector3df dir(pos-pivot);
                Quaternion quat(-x,cam_ec_placable->GetLocalYAxis());
                quat *= Quaternion(-y, cam_ec_placable->GetLocalXAxis());
                dir = quat * dir;

                Vector3df new_pos(pivot+dir);
                cam_ec_placable->SetPosition(new_pos);
                cam_ec_placable->LookAt(pivot);
            }
        }

        bool CameraHandler::ZoomRelativeToPoint(Vector3df point, CameraID id, qreal delta, qreal min, qreal max)
        {
            bool zoomed = false;
            if (id_to_cam_entity_.contains(id))
            {
                Scene::Entity *cam_entity = id_to_cam_entity_[id];
                OgreRenderer::EC_OgrePlaceable *placeable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
                if (!placeable)
                    return false;

                Vector3df pos = placeable->GetPosition();
                Vector3df dir = point-pos;
                Vector3df distance = dir;
                dir.normalize();
                dir *=delta;

                //something fishy, even if we check that we never go beyond min/max, we still might end up there and zoom will be disabled. So we check the also
                //if were zooming in or out.
                if(delta>0 && (distance.getLength()+dir.getLength() > min))
                {
                    zoomed = true;
                }
                if(delta<0 && (distance.getLength()+dir.getLength() <max))
                {
                    zoomed = true;
                }
                if(zoomed)
                {
                    placeable->SetPosition(placeable->GetPosition() + dir);
                    last_dir_ = dir;
                }
            }
            return zoomed;
        }

        QPixmap CameraHandler::RenderCamera(CameraID cam_id, QSize image_size)
        {
            // Get camera
            QImage captured_pixmap(image_size, QImage::Format_ARGB32_Premultiplied);
            captured_pixmap.fill(Qt::gray);

            // Check that this camera ID exists
            if (!id_to_cam_entity_.contains(cam_id))
                return QPixmap::fromImage(captured_pixmap);
            Scene::Entity *cam_entity = id_to_cam_entity_[cam_id];

            // Get the camera ec
            OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();
            if (!ec_camera)
                return QPixmap::fromImage(captured_pixmap);

            // Get our rendering texture
            Ogre::TexturePtr entity_viewport_texture = Ogre::TextureManager::getSingleton().getByName(render_texture_name_);
            if (entity_viewport_texture.isNull())
                return QPixmap::fromImage(captured_pixmap);

            // Re-create rendering texture if size has changed, this has to be done it seems with Ogre 1.7.1
            if (entity_viewport_texture->getWidth() != image_size.width() || entity_viewport_texture->getHeight() != image_size.height())
            {
                Ogre::TextureManager::getSingleton().remove(render_texture_name_);
                render_texture_name_ = "EntityViewPortTexture_" + QUuid::createUuid().toString().toStdString();
                entity_viewport_texture = Ogre::TextureManager::getSingleton().createManual(
                    render_texture_name_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                    Ogre::TEX_TYPE_2D, image_size.width(), image_size.height(), 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET);
                entity_viewport_texture->getBuffer()->getRenderTarget()->setAutoUpdated(false);
            }

            // Set camera aspect ratio
            ec_camera->GetCamera()->setAspectRatio(Ogre::Real(image_size.width()) / Ogre::Real(image_size.height()));

            // Get rendering texture and update it
            Ogre::RenderTexture *render_texture = entity_viewport_texture->getBuffer()->getRenderTarget();
            if (render_texture)
            {
                render_texture->removeAllViewports();
                if (render_texture->getNumViewports() == 0)
                {
                    Ogre::Viewport *vp = render_texture->addViewport(ec_camera->GetCamera());
                    vp->setOverlaysEnabled(false);
                    // Exclude highlight mesh from rendering
                    vp->setVisibilityMask(0x2);
                }
                render_texture->update();

                // Copy render target pixels into memory
                SAFE_DELETE(pixelData_);

                pixelData_ = new Ogre::uchar[image_size.height() * image_size.width() * 4];
                Ogre::Box bounds(0, 0, image_size.width(), image_size.height());
                Ogre::PixelBox pixels = Ogre::PixelBox(bounds, Ogre::PF_A8R8G8B8, (void*)pixelData_);

                //entity_viewport_texture->getBuffer()->blitToMemory(pixels);
                render_texture->copyContentsToMemory(pixels, Ogre::RenderTarget::FB_AUTO);

                // Create a QImage from the memory
                captured_pixmap = QImage(pixelData_, image_size.width(), image_size.height(), QImage::Format_ARGB32_Premultiplied);
                captured_pixmap.save("test.png");
                if (captured_pixmap.isNull())
                    WorldBuildingModule::LogDebug("Capturing entity to viewport image failed.");
            }
            // Return image as a QPixmap
            return QPixmap::fromImage(captured_pixmap);
        }
    }
}<commit_msg>*The building viewport will now remembers its orientation and relative position.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "CameraHandler.h"
#include "WorldBuildingModule.h"
#include "Quaternion.h"

#include <SceneManager.h>
#include <EC_OgrePlaceable.h>
#include <EC_OgreCamera.h>
#include <EC_OgreMesh.h>
#include <EC_OgreCustomObject.h>

#include <Ogre.h>
#include <QUuid>

#include <QDebug>

namespace WorldBuilding
{
    namespace View
    {
        CameraHandler::CameraHandler(Foundation::Framework *framework, QObject *parent) :
            QObject(parent),
            framework_(framework),
            camera_count_(0),
            pixelData_(0),
            last_dir_(Vector3df::ZERO)
        {
            render_texture_name_ = "EntityViewPortTexture_" + QUuid::createUuid().toString().toStdString();

            Ogre::TexturePtr entity_screenshot = Ogre::TextureManager::getSingleton().createManual(
                render_texture_name_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                Ogre::TEX_TYPE_2D, 1, 1, 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET);

            entity_screenshot->getBuffer()->getRenderTarget()->setAutoUpdated(false);
        }

        CameraHandler::~CameraHandler()
        {
            SAFE_DELETE(pixelData_);
        }

        CameraID CameraHandler::CreateCustomCamera()
        {
            Scene::ScenePtr scene = framework_->GetDefaultWorldScene();
            if (!scene)
                return -1;

            Scene::EntityPtr cam_entity = scene->CreateEntity(scene->GetNextFreeId());
            if (!cam_entity.get())
                return -1;

            cam_entity->AddComponent(framework_->GetComponentManager()->CreateComponent(OgreRenderer::EC_OgrePlaceable::TypeNameStatic()));
            cam_entity->AddComponent(framework_->GetComponentManager()->CreateComponent(OgreRenderer::EC_OgreCamera::TypeNameStatic()));

            Foundation::ComponentInterfacePtr component_placable = cam_entity->GetComponent(OgreRenderer::EC_OgrePlaceable::TypeNameStatic());
            OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();

            if (!component_placable.get() || !ec_camera)
                return -1;
            ec_camera->SetPlaceable(component_placable);

            camera_count_++;
            id_to_cam_entity_[camera_count_] = cam_entity.get();

            return camera_count_;
        }

        void CameraHandler::DestroyCamera(CameraID cam_id)
        {
            if (id_to_cam_entity_.contains(cam_id))
                id_to_cam_entity_.remove(cam_id);

            Ogre::TexturePtr entity_viewport_texture = Ogre::TextureManager::getSingleton().getByName(render_texture_name_);
            if (entity_viewport_texture.isNull())
                return;

            Ogre::RenderTexture *render_texture = entity_viewport_texture->getBuffer()->getRenderTarget();
            if (render_texture)
                render_texture->removeAllViewports();
        }

        bool CameraHandler::FocusToEntity(CameraID cam_id, Scene::Entity *entity, Vector3df offset)
        {

			bool focus_completed = false;

			if (!id_to_cam_entity_.contains(cam_id))
				return focus_completed;
			Scene::Entity *cam_entity = id_to_cam_entity_[cam_id];

			// Get placable from both focus entity and our camera id entity
			OgreRenderer::EC_OgrePlaceable *entity_ec_placable = entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
			OgreRenderer::EC_OgrePlaceable *cam_ec_placable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
			OgreRenderer::EC_OgreCamera *cam_ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();
	        if(last_dir_ == Vector3df::ZERO)
			{
				if (!entity_ec_placable || !cam_ec_placable || !cam_ec_camera)
					return focus_completed;

				OgreRenderer::EC_OgreMesh *entity_mesh = entity->GetComponent<OgreRenderer::EC_OgreMesh>().get();
				OgreRenderer::EC_OgreCustomObject *entity_custom_object = entity->GetComponent<OgreRenderer::EC_OgreCustomObject>().get();

				Vector3df position_vector = entity_ec_placable->GetPosition();
				Vector3df position_offset;
				Vector3df look_at;

				Vector3df bounding_min;
				Vector3df bounding_max;
				Vector3df der_size_vector;
				Ogre::Vector3 derived_scale;

				if (entity_mesh)
				{
					entity_mesh->GetBoundingBox(bounding_min, bounding_max);
					derived_scale = entity_mesh->GetEntity()->getParentNode()->_getDerivedScale();
					der_size_vector = Vector3df(derived_scale.x, derived_scale.y, derived_scale.z) * (bounding_max - bounding_min);

					position_offset = Vector3df(der_size_vector.x, -der_size_vector.y, der_size_vector.y);
					look_at = Vector3df(position_vector.x, position_vector.y, position_vector.z + (position_offset.z/2));
				}
				else if (entity_custom_object)
				{
					entity_custom_object->GetBoundingBox(bounding_min, bounding_max);
					derived_scale = entity_custom_object->GetEntity()->getParentNode()->_getDerivedScale();
					der_size_vector = Vector3df(derived_scale.x, derived_scale.y, derived_scale.z) * (bounding_max - bounding_min);

					float max_distance = 0;
					if (der_size_vector.x > max_distance)
						max_distance = der_size_vector.x;
					if (der_size_vector.y > max_distance)
						max_distance = der_size_vector.y;
					if (der_size_vector.z > max_distance)
						max_distance = der_size_vector.z;

					position_offset = Vector3df(der_size_vector.x, -max_distance, max_distance/4);
					look_at = Vector3df(position_vector.x, position_vector.y, position_vector.z + (position_offset.z/2));
				}
				else
					return focus_completed;

				cam_ec_placable->SetPosition(position_vector + (entity_ec_placable->GetOrientation() * position_offset));
				if (last_dir_ != Vector3df::ZERO)
				{
					//qDebug() << "Testig";
					//cam_ec_placable->SetPosition(cam_ec_placable->GetPosition() + last_dir_);
				}
				cam_ec_placable->LookAt(look_at);
				focus_completed = true;
			}else
			{
				cam_ec_placable->SetPosition(entity_ec_placable->GetPosition() - last_dir_);
				cam_ec_placable->LookAt(entity_ec_placable->GetPosition());
				focus_completed = true;
			}

				return focus_completed;
        }

        void CameraHandler::RotateCamera(Vector3df pivot, CameraID id, qreal x, qreal y)
        {
            if (id_to_cam_entity_.contains(id))
            {
                Scene::Entity *cam_entity = id_to_cam_entity_[id];
                OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();
                OgreRenderer::EC_OgrePlaceable *cam_ec_placable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
                if (!ec_camera || !cam_ec_placable)
                    return;

                Ogre::Camera* cam = ec_camera->GetCamera();
                Vector3df pos = cam_ec_placable->GetPosition();

                Vector3df dir(pos-pivot);
                Quaternion quat(-x,cam_ec_placable->GetLocalYAxis());
                quat *= Quaternion(-y, cam_ec_placable->GetLocalXAxis());
                dir = quat * dir;

                Vector3df new_pos(pivot+dir);
                cam_ec_placable->SetPosition(new_pos);
                cam_ec_placable->LookAt(pivot);

				last_dir_=pivot - cam_ec_placable->GetPosition();
            }
        }

        bool CameraHandler::ZoomRelativeToPoint(Vector3df point, CameraID id, qreal delta, qreal min, qreal max)
        {
            bool zoomed = false;
            if (id_to_cam_entity_.contains(id))
            {
                Scene::Entity *cam_entity = id_to_cam_entity_[id];
                OgreRenderer::EC_OgrePlaceable *placeable = cam_entity->GetComponent<OgreRenderer::EC_OgrePlaceable>().get();
                if (!placeable)
                    return false;

                Vector3df pos = placeable->GetPosition();
                Vector3df dir = point-pos;
                Vector3df distance = dir;
                dir.normalize();
                dir *=delta;

                //something fishy, even if we check that we never go beyond min/max, we still might end up there and zoom will be disabled. So we check the also
                //if were zooming in or out.
                if(delta>0 && (distance.getLength()+dir.getLength() > min))
                {
                    zoomed = true;
                }
                if(delta<0 && (distance.getLength()+dir.getLength() <max))
                {
                    zoomed = true;
                }
                if(zoomed)
                {
                    placeable->SetPosition(placeable->GetPosition() + dir);
					last_dir_ = point-placeable->GetPosition();
                }
            }
            return zoomed;
        }

        QPixmap CameraHandler::RenderCamera(CameraID cam_id, QSize image_size)
        {
            // Get camera
            QImage captured_pixmap(image_size, QImage::Format_ARGB32_Premultiplied);
            captured_pixmap.fill(Qt::gray);

            // Check that this camera ID exists
            if (!id_to_cam_entity_.contains(cam_id))
                return QPixmap::fromImage(captured_pixmap);
            Scene::Entity *cam_entity = id_to_cam_entity_[cam_id];

            // Get the camera ec
            OgreRenderer::EC_OgreCamera *ec_camera = cam_entity->GetComponent<OgreRenderer::EC_OgreCamera>().get();
            if (!ec_camera)
                return QPixmap::fromImage(captured_pixmap);

            // Get our rendering texture
            Ogre::TexturePtr entity_viewport_texture = Ogre::TextureManager::getSingleton().getByName(render_texture_name_);
            if (entity_viewport_texture.isNull())
                return QPixmap::fromImage(captured_pixmap);

            // Re-create rendering texture if size has changed, this has to be done it seems with Ogre 1.7.1
            if (entity_viewport_texture->getWidth() != image_size.width() || entity_viewport_texture->getHeight() != image_size.height())
            {
                Ogre::TextureManager::getSingleton().remove(render_texture_name_);
                render_texture_name_ = "EntityViewPortTexture_" + QUuid::createUuid().toString().toStdString();
                entity_viewport_texture = Ogre::TextureManager::getSingleton().createManual(
                    render_texture_name_, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                    Ogre::TEX_TYPE_2D, image_size.width(), image_size.height(), 0, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET);
                entity_viewport_texture->getBuffer()->getRenderTarget()->setAutoUpdated(false);
            }

            // Set camera aspect ratio
            ec_camera->GetCamera()->setAspectRatio(Ogre::Real(image_size.width()) / Ogre::Real(image_size.height()));

            // Get rendering texture and update it
            Ogre::RenderTexture *render_texture = entity_viewport_texture->getBuffer()->getRenderTarget();
            if (render_texture)
            {
                render_texture->removeAllViewports();
                if (render_texture->getNumViewports() == 0)
                {
                    Ogre::Viewport *vp = render_texture->addViewport(ec_camera->GetCamera());
                    vp->setOverlaysEnabled(false);
                    // Exclude highlight mesh from rendering
                    vp->setVisibilityMask(0x2);
                }
                render_texture->update();

                // Copy render target pixels into memory
                SAFE_DELETE(pixelData_);

                pixelData_ = new Ogre::uchar[image_size.height() * image_size.width() * 4];
                Ogre::Box bounds(0, 0, image_size.width(), image_size.height());
                Ogre::PixelBox pixels = Ogre::PixelBox(bounds, Ogre::PF_A8R8G8B8, (void*)pixelData_);

                //entity_viewport_texture->getBuffer()->blitToMemory(pixels);
                render_texture->copyContentsToMemory(pixels, Ogre::RenderTarget::FB_AUTO);

                // Create a QImage from the memory
                captured_pixmap = QImage(pixelData_, image_size.width(), image_size.height(), QImage::Format_ARGB32_Premultiplied);
                captured_pixmap.save("test.png");
                if (captured_pixmap.isNull())
                    WorldBuildingModule::LogDebug("Capturing entity to viewport image failed.");
            }
            // Return image as a QPixmap
            return QPixmap::fromImage(captured_pixmap);
        }
    }
}<|endoftext|>


<commit_before>808e1007-2749-11e6-b5ac-e0f84713e7b8<commit_msg>my cat is cute<commit_after>809ed2b0-2749-11e6-be00-e0f84713e7b8<|endoftext|>


<commit_before>/*
 *  The MIT License (MIT)
 *
 *  Copyright (c) 2015 MRL-SPL RoboCup Team
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 *
 */

/*
 * File:   Humanoid.cpp
 * Author: Mohammad Ali Sharpasand
 *
 * Created on February 8, 2016
 */

#include "Humanoid.hpp"
#include <ceres/ceres.h>
#include "glog/logging.h"
#include <cmath>

using ceres::NumericDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solver;
using ceres::Solve;
using ceres::CENTRAL;
using namespace BipedLibrary;

Humanoid::Humanoid(){}

Chain Humanoid::leftHand() const
{
    return leftHand_;
}

Chain Humanoid::rightHand() const
{
    return rightHand_;
}

Chain Humanoid::head() const
{
    return head_;
}

std::vector <vec3> Humanoid::detectedPoints() const
{
		return detectedPoints_;
}

std::vector <vec3> Humanoid::platePoints() const
{
		return platePoints_;
}

int Humanoid::cameraIndex() const
{
		return cameraIndex_;
}

std::vector <Camera> Humanoid::camera() const
{
		return camera_;
}

Humanoid& Humanoid::setLeftHand(Chain const& leftHand)
{
    leftHand_ = leftHand;
    return *this;
}

Humanoid& Humanoid::setRightHand(Chain const& rightHand)
{
    rightHand_ = rightHand;
    return *this;
}

Humanoid& Humanoid::setHead(Chain const& head)
{
    head_ = head;
    return *this;
}

Humanoid& Humanoid::setCamera(Camera const& camera)
{
		camera_.push_back(camera);
		return *this;
}

Humanoid& Humanoid::setCameraIndex(int const& cameraIndex)
{
		cameraIndex_ = cameraIndex;
		return *this;
}

Humanoid& Humanoid::setDetectedPoints(std::vector <vec3> detectedPoints)
{
		detectedPoints_ = detectedPoints;
		return *this;
}

Humanoid& Humanoid::setPlatePoints(std::vector <vec3> platePoints)
{
		platePoints_ = platePoints;
		return *this;
}

Chain& Humanoid::mutableLeftHand()
{
    return leftHand_;
}

Chain& Humanoid::mutableRightHand()
{
    return rightHand_;
}

Chain& Humanoid::mutableHead()
{
    return head_;
}

std::vector <Camera>& Humanoid::mutableCamera()
{
		return camera_;
}

std::vector <vec3>& Humanoid::mutableDetectedPoints()
{
		return detectedPoints_;
}

std::vector <vec3>& Humanoid::mutablePlatePoints()
{
		return platePoints_;
}

//static bool googleInitialized = false;

void Humanoid::calibrate()
{
//	if (!googleInitialized)
//	{
//		google::InitGoogleLogging("");
//		googleInitialized = true;
//	}
//
//	class f1 {
//	private:
//		Humanoid& humanoid_;
//	public:
//			f1(Humanoid& humanoid) : humanoid_(humanoid) { }
//		bool operator()(const double* const x1, double* residual) const {
//			residual[0] = x1[0] - 1;
//			residual[1] = x1[1] - 15;
////			humanoid_.mutableHead().at(0).mutableTheta() += x[0];
////			humanoid_.calculateErrors();
//			return true;
//		}
//	};
//
////	struct f2 {
////		bool operator()(const double* const x2, double* residual) const {
////			residual[0] = x2[0] - 3;
////			return true;
////		}
////	};
////
////	struct f3 {
////		bool operator()(const double* const x3, double* residual) const {
////			residual[0] = x3[0] + 3;
////			return true;
////		}
////	};
//	Problem problem;
//	double x1[2] = {0, 0}; double x2 = 0; double x3 = 0;
//	problem.AddResidualBlock(
//			new NumericDiffCostFunction<f1, CENTRAL, 2, 2>(new f1(*this)), NULL, x1);
////	problem.AddResidualBlock(
////			new NumericDiffCostFunction<f2, CENTRAL, 1, 1>(new f2), NULL, &x2);
////	problem.AddResidualBlock(
////			new NumericDiffCostFunction<f3, CENTRAL, 1, 1>(new f3), NULL, &x3);
//	Solver::Options options;
//	options.max_num_iterations = 100;
//	options.linear_solver_type = ceres::DENSE_QR;
//	options.minimizer_progress_to_stdout = true;
//	Solver::Summary summary;
//	Solve(options, &problem, &summary);
////	std::cout << summary.FullReport() << "\n";
}

void Humanoid::calculateErrors()
{
//		//PART 1: here posi_C_B_B and ori_C_B are calculated.
//		// section 1, from Torso to Base by right leg
//		const vec3 posi_RF_T_T = rightLeg().position_end_body_body();
//		const vec3 posi_RF_B_B = {0,-50,0};
//		const mat33 ori_RF_T = rightLeg().orientation_end_body();
//		const mat33 ori_rT_B = trans(ori_RF_T);
//		const vec3 posi_rT_B_B = - ori_rT_B * posi_RF_T_T + posi_RF_B_B;
//
//		// section 1.5, from Torso to Base by left leg
//		const vec3 posi_LF_T_T = leftLeg().position_end_body_body();
//		const vec3 posi_LF_B_B = {0,50,0};
//		const mat33 ori_LF_T = leftLeg().orientation_end_body();
//		const mat33 ori_lT_B = trans(ori_LF_T);
//		const vec3 posi_lT_B_B = - ori_lT_B * posi_LF_T_T + posi_LF_B_B;
//
//		//section 1.6
//		const vec3 posi_T_B_B = ( posi_lT_B_B + posi_rT_B_B ) / 2;
//		const mat33 ori_T_B = ( ori_rT_B + ori_lT_B ) / 2;
//
//		//section 2, from Head to Base
//		const vec3 posi_H_T_T = head().position_end_body_body();
//		const mat33 ori_H_T = head().orientation_end_body();
//		const mat33 ori_H_B = ori_T_B * ori_H_T;
//		const vec3 posi_H_B_B = ori_T_B * posi_H_T_T + posi_T_B_B;
//
//		int cameraNumber;
//		//section 3, from Camera to Base
//		vec3 posi_C_H_H = camera().at(cameraNumber).position();
//		mat33 ori_C_H = camera().at(cameraNumber).orientation();
//
//		mat33 ori_C_B = ori_H_B * ori_C_H;
//		mat33 ori_I_B = ori_C_B * AxisAngle( { 0, 1, 0 },  M_PI_2).rotationMatrix()
//																										* AxisAngle( { 0, 0, 1 }, -M_PI_2).rotationMatrix();
//		vec3 posi_C_B_B = ori_H_B * posi_C_H_H + posi_H_B_B;
//
//
//		float f_C = camera().at(cameraNumber).imageSize().at(0) / (2 *  std::tan(camera().at(cameraNumber).openAngle().toFloat() / 2));
//		//PART 2: here sample points from plate of current state get sorted
//		// in order to get their difference with ordered points from plate
//		std::vector<vec_index> unprojectedPoints;
//		for (size_t i=0; i<detectedPoints().size(); i++)
//				{
//						vec3 posi_Pi_C_C ;
//						posi_Pi_C_C.at(0) = detectedPoints().at(i).at(0) - (camera().at(cameraNumber).imageSize().at(0) / 2);
//						posi_Pi_C_C.at(1) = detectedPoints().at(i).at(1) - (camera().at(cameraNumber).imageSize().at(1) / 2);
//
//						posi_Pi_C_C.at(2) = f_C;
//						vec3 posi_Pi_C_B = ori_I_B * posi_Pi_C_C;
//
//						float a = - posi_C_B_B.at(2) / posi_Pi_C_B.at(2);
//						vec3 posi_P_C_B = a * posi_Pi_C_B;
//						vec3 posi_P_B_B = posi_C_B_B + posi_P_C_B;
//
//						vec_index newPoint;
//						newPoint.index = i;
//						newPoint.point = posi_P_B_B;
//
//						unprojectedPoints.push_back(newPoint);
//				}
//
//		std::sort (unprojectedPoints.begin(), unprojectedPoints.end(), [](const vec_index& a, const vec_index& b) {
//				return a.point[0] < b.point[0];
//		});
//		std::sort (unprojectedPoints.begin(), unprojectedPoints.begin()+2, [](const vec_index& a, const vec_index& b) {
//				return a.point[1] < b.point[1];
//		});
//		std::sort (unprojectedPoints.begin()+3, unprojectedPoints.begin()+5, [](const vec_index& a, const vec_index& b) {
//				return a.point[1] < b.point[1];
//		});
//		std::sort (unprojectedPoints.begin()+6, unprojectedPoints.end(), [](const vec_index& a, const vec_index& b) {
//				return a.point[1] < b.point[1];
//		});
//
//		//PART 3: here point errors are calculated and added to platePoints vector
//		for (size_t i=0; i<detectedPoints().size(); i++)
//				{
//						vec3 posi_Pw_B_B = platePoints().at(i);
//						vec3 posi_Pw_C_C = trans(ori_I_B) * (posi_Pw_B_B - posi_C_B_B);
//
//						float a = posi_Pw_C_C.at(2) / f_C;
//
//						//section 5
//						vec3 posi_Pi_C_C;
//						posi_Pi_C_C.at(0) = (1/a) * posi_Pw_C_C.at(0);
//						posi_Pi_C_C.at(1) = (1/a) * posi_Pw_C_C.at(1);
//						posi_Pi_C_C.at(2) = f_C;
//
//						float Width = camera().at(cameraNumber).imageSize().at(0) , Height = camera().at(cameraNumber).imageSize().at(1);
//						float xi = posi_Pi_C_C.at(0) + Width/2;
//						float yi = posi_Pi_C_C.at(1) + Height/2;
//
//						vec2 newPoint = {detectedPoints().at(unprojectedPoints.at(i).index).at(0) - xi,
//																							detectedPoints().at(unprojectedPoints.at(i).index).at(1) - yi};
////						PlatePoints.push_back(newPoint);
//				}
}
<commit_msg>removing calibrate function from humanoid.cpp<commit_after>/*
 *  The MIT License (MIT)
 *
 *  Copyright (c) 2015 MRL-SPL RoboCup Team
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in all
 *  copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *  SOFTWARE.
 *
 */

/*
 * File:   Humanoid.cpp
 * Author: Mohammad Ali Sharpasand
 *
 * Created on February 8, 2016
 */

#include "Humanoid.hpp"
#include <ceres/ceres.h>
#include "glog/logging.h"
#include <cmath>

using ceres::NumericDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solver;
using ceres::Solve;
using ceres::CENTRAL;
using namespace BipedLibrary;

Humanoid::Humanoid(){}

Chain Humanoid::leftHand() const
{
    return leftHand_;
}

Chain Humanoid::rightHand() const
{
    return rightHand_;
}

Chain Humanoid::head() const
{
    return head_;
}

std::vector <vec3> Humanoid::detectedPoints() const
{
		return detectedPoints_;
}

std::vector <vec3> Humanoid::platePoints() const
{
		return platePoints_;
}

int Humanoid::cameraIndex() const
{
		return cameraIndex_;
}

std::vector <Camera> Humanoid::camera() const
{
		return camera_;
}

Humanoid& Humanoid::setLeftHand(Chain const& leftHand)
{
    leftHand_ = leftHand;
    return *this;
}

Humanoid& Humanoid::setRightHand(Chain const& rightHand)
{
    rightHand_ = rightHand;
    return *this;
}

Humanoid& Humanoid::setHead(Chain const& head)
{
    head_ = head;
    return *this;
}

Humanoid& Humanoid::setCamera(Camera const& camera)
{
		camera_.push_back(camera);
		return *this;
}

Humanoid& Humanoid::setCameraIndex(int const& cameraIndex)
{
		cameraIndex_ = cameraIndex;
		return *this;
}

Humanoid& Humanoid::setDetectedPoints(std::vector <vec3> detectedPoints)
{
		detectedPoints_ = detectedPoints;
		return *this;
}

Humanoid& Humanoid::setPlatePoints(std::vector <vec3> platePoints)
{
		platePoints_ = platePoints;
		return *this;
}

Chain& Humanoid::mutableLeftHand()
{
    return leftHand_;
}

Chain& Humanoid::mutableRightHand()
{
    return rightHand_;
}

Chain& Humanoid::mutableHead()
{
    return head_;
}

std::vector <Camera>& Humanoid::mutableCamera()
{
		return camera_;
}

std::vector <vec3>& Humanoid::mutableDetectedPoints()
{
		return detectedPoints_;
}

std::vector <vec3>& Humanoid::mutablePlatePoints()
{
		return platePoints_;
}

//static bool googleInitialized = false;

void Humanoid::calibrate()
{
//	if (!googleInitialized)
//	{
//		google::InitGoogleLogging("");
//		googleInitialized = true;
//	}
//
//	class f1 {
//	private:
//		Humanoid& humanoid_;
//	public:
//			f1(Humanoid& humanoid) : humanoid_(humanoid) { }
//		bool operator()(const double* const x1, double* residual) const {
//			residual[0] = x1[0] - 1;
//			residual[1] = x1[1] - 15;
////			humanoid_.mutableHead().at(0).mutableTheta() += x[0];
////			humanoid_.calculateErrors();
//			return true;
//		}
//	};
//
////	struct f2 {
////		bool operator()(const double* const x2, double* residual) const {
////			residual[0] = x2[0] - 3;
////			return true;
////		}
////	};
////
////	struct f3 {
////		bool operator()(const double* const x3, double* residual) const {
////			residual[0] = x3[0] + 3;
////			return true;
////		}
////	};
//	Problem problem;
//	double x1[2] = {0, 0}; double x2 = 0; double x3 = 0;
//	problem.AddResidualBlock(
//			new NumericDiffCostFunction<f1, CENTRAL, 2, 2>(new f1(*this)), NULL, x1);
////	problem.AddResidualBlock(
////			new NumericDiffCostFunction<f2, CENTRAL, 1, 1>(new f2), NULL, &x2);
////	problem.AddResidualBlock(
////			new NumericDiffCostFunction<f3, CENTRAL, 1, 1>(new f3), NULL, &x3);
//	Solver::Options options;
//	options.max_num_iterations = 100;
//	options.linear_solver_type = ceres::DENSE_QR;
//	options.minimizer_progress_to_stdout = true;
//	Solver::Summary summary;
//	Solve(options, &problem, &summary);
////	std::cout << summary.FullReport() << "\n";
}

<|endoftext|>


<commit_before><commit_msg>gltfio: show warning for missing normals.<commit_after><|endoftext|>


<commit_before>//---
//
// License: MIT
//
// Author:  David Burken
//
// Description: Container class for J2K Image and tile size (SIZ) record.
//
// See document BPJ2K01.00 Table 7-6 Image and tile size (15444-1 Annex A5.1)
//
//---
// $Id$

#include <ossim/support_data/ossimJ2kSizRecord.h>
#include <ossim/base/ossimConstants.h>
#include <ossim/base/ossimCommon.h>
#include <ossim/base/ossimEndian.h>
#include <ossim/base/ossimIoStream.h>
#include <iostream>
#include <iomanip>

ossimJ2kSizRecord::ossimJ2kSizRecord()
   :
   m_marker(0xff51),
   m_Lsiz(0),
   m_Rsiz(0),
   m_Xsiz(0),
   m_Ysiz(0),
   m_XOsiz(0),
   m_YOsiz(0),
   m_XTsiz(0),
   m_YTsiz(0),
   m_XTOsiz(0),
   m_YTOsiz(0),
   m_Csiz(0),
   m_Ssiz(0),
   m_XRsiz(0),
   m_YRsiz(0)
{
}

ossimJ2kSizRecord::~ossimJ2kSizRecord()
{
}

void ossimJ2kSizRecord::parseStream(ossim::istream& in)
{
   // Note: Marker is not read.
   in.read((char*)&m_Lsiz,      2);
   in.read((char*)&m_Rsiz,      2);
   in.read((char*)&m_Xsiz,      4);
   in.read((char*)&m_Ysiz,      4);
   in.read((char*)&m_XOsiz,     4);
   in.read((char*)&m_YOsiz,     4);
   in.read((char*)&m_XTsiz,     4);
   in.read((char*)&m_YTsiz,     4);
   in.read((char*)&m_XTOsiz,    4);
   in.read((char*)&m_YTOsiz,    4);
   in.read((char*)&m_Csiz,      2);

   if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN)
   {
      // Stored in file big endian, must swap.
      ossimEndian s;
      s.swap(m_Lsiz);
      s.swap(m_Rsiz);
      s.swap(m_Xsiz);
      s.swap(m_Ysiz);
      s.swap(m_XOsiz);
      s.swap(m_YOsiz);
      s.swap(m_XTsiz);
      s.swap(m_YTsiz);
      s.swap(m_XTOsiz);
      s.swap(m_YTOsiz);
      s.swap(m_Csiz);
   }

   m_Ssiz.resize( m_Csiz );
   in.read((char*)&m_Ssiz.front(), m_Csiz);

   m_XRsiz.resize( m_Csiz );
   in.read((char*)&m_XRsiz.front(), m_Csiz);

   m_YRsiz.resize( m_Csiz );
   in.read((char*)&m_YRsiz.front(), m_Csiz);
}

void ossimJ2kSizRecord::writeStream(std::ostream& out)
{
   // Length of this marker segment(marker not included):
   m_Lsiz = 38 + 3*m_Csiz;

   // Grab component count before swapping:
   ossim_uint16 components = m_Csiz;

   ossimEndian* s = 0;

   if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN)
   {
      // Stored in file big endian, must swap.
      s = new ossimEndian();
      s->swap(m_Lsiz);
      s->swap(m_Rsiz);
      s->swap(m_Xsiz);
      s->swap(m_Ysiz);
      s->swap(m_XOsiz);
      s->swap(m_YOsiz);
      s->swap(m_XTsiz);
      s->swap(m_YTsiz);
      s->swap(m_XTOsiz);
      s->swap(m_YTOsiz);
      s->swap(m_Csiz);
   }

   out.write( (char*)&m_marker, 2 );
   out.write((char*)&m_Lsiz,    2);
   out.write((char*)&m_Rsiz,    2);
   out.write((char*)&m_Xsiz,    4);
   out.write((char*)&m_Ysiz,    4);
   out.write((char*)&m_XOsiz,   4);
   out.write((char*)&m_YOsiz,   4);
   out.write((char*)&m_XTsiz,   4);
   out.write((char*)&m_YTsiz,   4);
   out.write((char*)&m_XTOsiz,  4);
   out.write((char*)&m_YTOsiz,  4);
   out.write((char*)&m_Csiz,    2);

   out.write((char*)&m_Ssiz.front(),  components);
   out.write((char*)&m_XRsiz.front(), components);
   out.write((char*)&m_YRsiz.front(), components);

   if ( s )
   {
      // Swap it back to native.
      s->swap(m_Lsiz);
      s->swap(m_Rsiz);
      s->swap(m_Xsiz);
      s->swap(m_Ysiz);
      s->swap(m_XOsiz);
      s->swap(m_YOsiz);
      s->swap(m_XTsiz);
      s->swap(m_YTsiz);
      s->swap(m_XTOsiz);
      s->swap(m_YTOsiz);
      s->swap(m_Csiz);
   }
}

ossimScalarType ossimJ2kSizRecord::getScalarType() const
{
   // Currently assumes all components the same scalar type.

   ossimScalarType result = OSSIM_SCALAR_UNKNOWN;

   if ( m_Ssiz.size() )
   {
      // Bits per pixel first seven bits plus one.
      ossim_uint8 bpp = ( m_Ssiz[0] & 0x3f ) + 1;

      // Signed bit is msb.
      bool isSigned = ( m_Ssiz[0] & 0x80 ) ? true : false;

      if ( bpp <= 8 )
      {
         if ( isSigned == 0 )
         {
            result = OSSIM_UINT8;
         }
         else if (isSigned == 1)
         {
            result = OSSIM_SINT8;
         }
      }
      else if ( bpp == 11 )
      {
         if ( isSigned == 0 )
         {
            result = OSSIM_USHORT11;
         }
         else
         {
            result = OSSIM_SINT16;
         }
      }
      else if( bpp <= 16 )
      {
         if( isSigned == 0 )
         {
            result = OSSIM_UINT16;
         }
         else if( isSigned == 1 )
         {
            result = OSSIM_SINT16;
         }
      }
   }
   return result;
}

std::ostream& ossimJ2kSizRecord::print(std::ostream& out,
                                       const std::string& prefix) const
{
   // Capture the original flags.
   std::ios_base::fmtflags f = out.flags();

   std::string pfx = prefix;
   pfx += "siz.";

   out.setf(std::ios_base::hex, std::ios_base::basefield);
   out << pfx << "marker: 0x" << m_marker << "\n";
   out.setf(std::ios_base::fmtflags(0), std::ios_base::basefield);

   out << pfx << "Lsiz:   " << m_Lsiz       << "\n"
       << pfx << "Rsiz:   " << m_Rsiz       << "\n"
       << pfx << "Xsiz:   " << m_Xsiz       << "\n"
       << pfx << "Yziz:   " << m_Ysiz       << "\n"
       << pfx << "XOsiz:  " << m_XOsiz      << "\n"
       << pfx << "YOsiz:  " << m_YOsiz      << "\n"
       << pfx << "XTsiz:  " << m_XTsiz      << "\n"
       << pfx << "YTsiz:  " << m_YTsiz      << "\n"
       << pfx << "XTOsiz: " << m_XTOsiz     << "\n"
       << pfx << "YTOsiz: " << m_YTOsiz     << "\n"
       << pfx << "Csiz:   " << m_Csiz       << "\n";

   for ( ossim_uint16 i = 0; i < m_Csiz; ++i )
   {
      out << pfx << "Ssiz[" << i  << "]:  " << int(m_Ssiz[i])  << "\n"
          << pfx << "XRsiz[" << i << "]:  " << int(m_XRsiz[i]) << "\n"
          << pfx << "YRsiz[" << i << "]:  " << int(m_YRsiz[i]) << "\n";
   }

   out.flush();

   // Reset flags.
   out.setf(f);

   return out;
}

std::ostream& operator<<(std::ostream& out, const ossimJ2kSizRecord& obj)
{
   return obj.print(out);
}
<commit_msg>Fixed leak.<commit_after>//---
//
// License: MIT
//
// Author:  David Burken
//
// Description: Container class for J2K Image and tile size (SIZ) record.
//
// See document BPJ2K01.00 Table 7-6 Image and tile size (15444-1 Annex A5.1)
//
//---
// $Id$

#include <ossim/support_data/ossimJ2kSizRecord.h>
#include <ossim/base/ossimConstants.h>
#include <ossim/base/ossimCommon.h>
#include <ossim/base/ossimEndian.h>
#include <ossim/base/ossimIoStream.h>
#include <iostream>
#include <iomanip>

ossimJ2kSizRecord::ossimJ2kSizRecord()
   :
   m_marker(0xff51),
   m_Lsiz(0),
   m_Rsiz(0),
   m_Xsiz(0),
   m_Ysiz(0),
   m_XOsiz(0),
   m_YOsiz(0),
   m_XTsiz(0),
   m_YTsiz(0),
   m_XTOsiz(0),
   m_YTOsiz(0),
   m_Csiz(0),
   m_Ssiz(0),
   m_XRsiz(0),
   m_YRsiz(0)
{
}

ossimJ2kSizRecord::~ossimJ2kSizRecord()
{
}

void ossimJ2kSizRecord::parseStream(ossim::istream& in)
{
   // Note: Marker is not read.
   in.read((char*)&m_Lsiz,      2);
   in.read((char*)&m_Rsiz,      2);
   in.read((char*)&m_Xsiz,      4);
   in.read((char*)&m_Ysiz,      4);
   in.read((char*)&m_XOsiz,     4);
   in.read((char*)&m_YOsiz,     4);
   in.read((char*)&m_XTsiz,     4);
   in.read((char*)&m_YTsiz,     4);
   in.read((char*)&m_XTOsiz,    4);
   in.read((char*)&m_YTOsiz,    4);
   in.read((char*)&m_Csiz,      2);

   if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN)
   {
      // Stored in file big endian, must swap.
      ossimEndian s;
      s.swap(m_Lsiz);
      s.swap(m_Rsiz);
      s.swap(m_Xsiz);
      s.swap(m_Ysiz);
      s.swap(m_XOsiz);
      s.swap(m_YOsiz);
      s.swap(m_XTsiz);
      s.swap(m_YTsiz);
      s.swap(m_XTOsiz);
      s.swap(m_YTOsiz);
      s.swap(m_Csiz);
   }

   m_Ssiz.resize( m_Csiz );
   in.read((char*)&m_Ssiz.front(), m_Csiz);

   m_XRsiz.resize( m_Csiz );
   in.read((char*)&m_XRsiz.front(), m_Csiz);

   m_YRsiz.resize( m_Csiz );
   in.read((char*)&m_YRsiz.front(), m_Csiz);
}

void ossimJ2kSizRecord::writeStream(std::ostream& out)
{
   // Length of this marker segment(marker not included):
   m_Lsiz = 38 + 3*m_Csiz;

   // Grab component count before swapping:
   ossim_uint16 components = m_Csiz;

   ossimEndian* s = 0;

   if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN)
   {
      // Stored in file big endian, must swap.
      s = new ossimEndian();
      s->swap(m_Lsiz);
      s->swap(m_Rsiz);
      s->swap(m_Xsiz);
      s->swap(m_Ysiz);
      s->swap(m_XOsiz);
      s->swap(m_YOsiz);
      s->swap(m_XTsiz);
      s->swap(m_YTsiz);
      s->swap(m_XTOsiz);
      s->swap(m_YTOsiz);
      s->swap(m_Csiz);
   }

   out.write( (char*)&m_marker, 2 );
   out.write((char*)&m_Lsiz,    2);
   out.write((char*)&m_Rsiz,    2);
   out.write((char*)&m_Xsiz,    4);
   out.write((char*)&m_Ysiz,    4);
   out.write((char*)&m_XOsiz,   4);
   out.write((char*)&m_YOsiz,   4);
   out.write((char*)&m_XTsiz,   4);
   out.write((char*)&m_YTsiz,   4);
   out.write((char*)&m_XTOsiz,  4);
   out.write((char*)&m_YTOsiz,  4);
   out.write((char*)&m_Csiz,    2);

   out.write((char*)&m_Ssiz.front(),  components);
   out.write((char*)&m_XRsiz.front(), components);
   out.write((char*)&m_YRsiz.front(), components);

   if ( s )
   {
      // Swap it back to native.
      s->swap(m_Lsiz);
      s->swap(m_Rsiz);
      s->swap(m_Xsiz);
      s->swap(m_Ysiz);
      s->swap(m_XOsiz);
      s->swap(m_YOsiz);
      s->swap(m_XTsiz);
      s->swap(m_YTsiz);
      s->swap(m_XTOsiz);
      s->swap(m_YTOsiz);
      s->swap(m_Csiz);

      // Cleanup:
      delete s;
      s = 0;
   }
}

ossimScalarType ossimJ2kSizRecord::getScalarType() const
{
   // Currently assumes all components the same scalar type.

   ossimScalarType result = OSSIM_SCALAR_UNKNOWN;

   if ( m_Ssiz.size() )
   {
      // Bits per pixel first seven bits plus one.
      ossim_uint8 bpp = ( m_Ssiz[0] & 0x3f ) + 1;

      // Signed bit is msb.
      bool isSigned = ( m_Ssiz[0] & 0x80 ) ? true : false;

      if ( bpp <= 8 )
      {
         if ( isSigned == 0 )
         {
            result = OSSIM_UINT8;
         }
         else if (isSigned == 1)
         {
            result = OSSIM_SINT8;
         }
      }
      else if ( bpp == 11 )
      {
         if ( isSigned == 0 )
         {
            result = OSSIM_USHORT11;
         }
         else
         {
            result = OSSIM_SINT16;
         }
      }
      else if( bpp <= 16 )
      {
         if( isSigned == 0 )
         {
            result = OSSIM_UINT16;
         }
         else if( isSigned == 1 )
         {
            result = OSSIM_SINT16;
         }
      }
   }
   return result;
}

std::ostream& ossimJ2kSizRecord::print(std::ostream& out,
                                       const std::string& prefix) const
{
   // Capture the original flags.
   std::ios_base::fmtflags f = out.flags();

   std::string pfx = prefix;
   pfx += "siz.";

   out.setf(std::ios_base::hex, std::ios_base::basefield);
   out << pfx << "marker: 0x" << m_marker << "\n";
   out.setf(std::ios_base::fmtflags(0), std::ios_base::basefield);

   out << pfx << "Lsiz:   " << m_Lsiz       << "\n"
       << pfx << "Rsiz:   " << m_Rsiz       << "\n"
       << pfx << "Xsiz:   " << m_Xsiz       << "\n"
       << pfx << "Yziz:   " << m_Ysiz       << "\n"
       << pfx << "XOsiz:  " << m_XOsiz      << "\n"
       << pfx << "YOsiz:  " << m_YOsiz      << "\n"
       << pfx << "XTsiz:  " << m_XTsiz      << "\n"
       << pfx << "YTsiz:  " << m_YTsiz      << "\n"
       << pfx << "XTOsiz: " << m_XTOsiz     << "\n"
       << pfx << "YTOsiz: " << m_YTOsiz     << "\n"
       << pfx << "Csiz:   " << m_Csiz       << "\n";

   for ( ossim_uint16 i = 0; i < m_Csiz; ++i )
   {
      out << pfx << "Ssiz[" << i  << "]:  " << int(m_Ssiz[i])  << "\n"
          << pfx << "XRsiz[" << i << "]:  " << int(m_XRsiz[i]) << "\n"
          << pfx << "YRsiz[" << i << "]:  " << int(m_YRsiz[i]) << "\n";
   }

   out.flush();

   // Reset flags.
   out.setf(f);

   return out;
}

std::ostream& operator<<(std::ostream& out, const ossimJ2kSizRecord& obj)
{
   return obj.print(out);
}
<|endoftext|>


<commit_before>/**
 *  machina
 *
 *  Copyright (c) 2014, drmats
 *  All rights reserved.
 *
 *  https://github.com/drmats/machina
 */

#ifndef __SHADER_CPP_
#define __SHADER_CPP_ 1

#include "shader.hpp"

namespace machina {

/**
 *  Shader source helper macro.
 */
#define GLSL(version, src) "#version " #version "\n" #src

/**
 *  OpenGL messages buffer.
 */
GLchar Shader::message_buffer[GL_INFO_LOG_LENGTH] { 0 };

/**
 *  Some shader sources.
 */
// basic vertex shader -- care about vertex position
const std::string Shader::vs_basic = GLSL(130,
    uniform mat4 mvp_matrix;
    in vec3 vertex_position;

    void main (void) {
        gl_Position = mvp_matrix * vec4(vertex_position, 1);
    }
);

// basic fragment shader -- care about fragment color (from uniform)
const std::string Shader::fs_basic_color_uniform = GLSL(130,
    uniform vec4 uniform_color;
    out vec4 fragment_color;

    void main (void) {
        fragment_color = uniform_color;
    }
);

// basic vertex shader -- care about vertex position and color
const std::string Shader::vs_basic_attribute_color = GLSL(130,
    uniform mat4 mvp_matrix;
    in vec3 vertex_position;
    in vec4 vertex_color;
    smooth out vec4 vertex_fragment_color;

    void main (void) {
        vertex_fragment_color = vertex_color;
        gl_Position = mvp_matrix * vec4(vertex_position, 1);
    }
);

// basic fragment shader -- care about fragment color (from vs)
const std::string Shader::fs_basic_color_in = GLSL(130,
    smooth in vec4 vertex_fragment_color;
    out vec4 fragment_color;

    void main (void) {
        fragment_color = vertex_fragment_color;
    }
);

// all attrib vertex shader
const std::string Shader::vs_all_attrib = GLSL(130,
    precision highp float;

    in vec3 vert_position;
    in vec3 vert_normal;
    in vec2 vert_uv;

    uniform mat4 mv_matrix;
    uniform mat4 p_matrix;

    smooth out vec3 frag_normal;
    smooth out vec3 frag_position;
    smooth out vec3 frag_mv_position;

    vec4 mv_position = mv_matrix * vec4(vert_position, 1);
    mat3 normal_matrix;

    void main (void) {
        normal_matrix[0] = mv_matrix[0].xyz;
        normal_matrix[1] = mv_matrix[1].xyz;
        normal_matrix[2] = mv_matrix[2].xyz;

        frag_position = vert_position;
        frag_mv_position = mv_position.xyz;
        frag_normal = normalize(normal_matrix * vert_normal);

        gl_Position = p_matrix * mv_position;
    }
);

// all attrib fragment shader
const std::string Shader::fs_all_attrib = GLSL(130,
    precision highp float;

    uniform vec4 color;
    uniform vec3 light_direction;

    smooth in vec3 frag_position;
    smooth in vec3 frag_mv_position;
    smooth in vec3 frag_normal;

    out vec4 out_color;

    // const vec3 light_direction = vec3(0.0, 0.0, 1.0);
    // vec3 mv_light_direction = (mv_matrix * vec4(light_direction, 1.0)).xyz;

    // void main (void) {
    //     // mix position and normal as color
    //     // out_color = vec4(
    //     //     mix(
    //     //         normalize(abs(frag_position)),
    //     //         frag_normal,
    //     //         0.5
    //     //     ), 1
    //     // );

    //     // simple directional light
    //     out_color.rgb =
    //         color.rgb * max(0.0, dot(frag_normal, light_direction));
    //     out_color.a = color.a;
    // }

    vec2 phong_blinn_directional (
        vec3 direction, float intensity,
        float ambient, float diffuse, float specular, float shininess
    ) {
        vec3 s = normalize(direction);
        vec3 v = normalize(-frag_mv_position);
        vec3 normal = normalize(frag_normal);
        vec3 h = normalize(v + s);
        return vec2(
            ambient + diffuse * intensity * max(0.0, dot(normal, s)),
            specular * pow(max(0.0, dot(normal, h)), shininess)
        );
    }

    // vec3 rim_light (vec3 color, float start, float end, float coef) {
    //   vec3 normal = normalize(frag_normal);
    //   vec3 eye = normalize(-frag_mv_position.xyz);
    //   float rim = smoothstep(start, end, 1.0 - dot(normal, eye));
    //   return clamp(rim, 0.0, 1.0) * coef * color;
    // }

    void main () {
        vec2 params = phong_blinn_directional(
            light_direction, 16.0,
            0.1, 0.2, 0.8, 256.0
        );
        out_color.rgb = mix(params.x * color.rgb,  params.y * color.rgb, 0.8);
        out_color.a = color.a;
    }
);

/**
 *  Initialization with attribute binding.
 *  Example invocation:
 *      Shader some_shader {
 *          shader::vs_basic,
 *          shader::fs_basic, {
 *              std::make_tuple(
 *                  "vertex_position", Shader::attrib_index::vertex
 *              )
 *      } };
 */
Shader::Shader (
    const std::string &vs, const std::string &fs,
    const std::initializer_list<
        std::tuple<std::string, Shader::attrib_index>
    > binding
) throw (std::runtime_error) {
    // temporary shader objects (load and compile from sources)
    GLuint
        vertex_shader { this->load_shader(GL_VERTEX_SHADER, vs) },
        fragment_shader { this->load_shader(GL_FRAGMENT_SHADER, fs) };

    // status variable (for testing errors)
    GLint status;

    // attach shaders to gl program
    this->program = glCreateProgram();
    glAttachShader(this->program, vertex_shader);
    glAttachShader(this->program, fragment_shader);

    // bind attributes to the gl program
    for (auto it = binding.begin();  it != binding.end();  it++) {
        glBindAttribLocation(
            this->program,
            std::get<1>(*it),
            std::get<0>(*it).data()
        );
    }

    // link gl program
    glLinkProgram(this->program);

    // temporary shaders are no longer needed
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);

    // check for link errors
    glGetProgramiv(this->program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE) {
        std::string error_message {
            this->get_program_info_log(this->program)
        };
        glDeleteProgram(this->program);
        throw std::runtime_error(error_message);
    }
}

/**
 *  Clean-up.
 */
Shader::~Shader () {
    if (this->program != 0) {
        glDeleteProgram(this->program);
        this->program = 0;
    }
}

/**
 *  Assign uniforms and use shader.
 *  Example invocation:
 *      some_shader.use({
 *          std::make_tuple("mvp_matrix", [&] (GLuint location) {
 *              glUniformMatrix4fv(location, 1, GL_FALSE, *mvp_matrix);
 *          })
 *      });
 */
const Shader& Shader::use (
    std::initializer_list<
        std::tuple<std::string, std::function<void (GLint)>>
    > uniforms
) const {
    glUseProgram(this->program);

    for (auto it = uniforms.begin();  it != uniforms.end();  it++) {
        std::get<1>(*it)(
            glGetUniformLocation(
                this->program, (GLchar*)std::get<0>(*it).data()
            )
        );
    }

    return *this;
}

/**
 *  Compile shader from a given source.
 */
GLuint Shader::load_shader (
    GLenum shader_type,
    const std::string &shader_src
) throw (std::runtime_error) {
    GLuint shader { glCreateShader(shader_type) };
    const GLchar *src { (GLchar*)shader_src.data() };
    GLint status;

    glShaderSource(shader, 1, &src, NULL);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
        std::string error_message {
            this->get_shader_info_log(shader)
        };
        glDeleteShader(shader);
        throw std::runtime_error(error_message);
    }

    return shader;
}

/**
 *  Get shader compilation log message.
 */
std::string Shader::get_shader_info_log (GLuint shader) {
    glGetShaderInfoLog(
        shader, GL_INFO_LOG_LENGTH, NULL, Shader::message_buffer
    );
    return "GLSL shader: " + std::string(Shader::message_buffer);
}

/**
 *  Get program linking log.
 */
std::string Shader::get_program_info_log (GLuint program) {
    glGetProgramInfoLog(
        program, GL_INFO_LOG_LENGTH, NULL, Shader::message_buffer
    );
    return "GLSL program: " + std::string(Shader::message_buffer);
}

} // namespace machina

#endif
<commit_msg>Shader: edge darkening.<commit_after>/**
 *  machina
 *
 *  Copyright (c) 2014, drmats
 *  All rights reserved.
 *
 *  https://github.com/drmats/machina
 */

#ifndef __SHADER_CPP_
#define __SHADER_CPP_ 1

#include "shader.hpp"

namespace machina {

/**
 *  Shader source helper macro.
 */
#define GLSL(version, src) "#version " #version "\n" #src

/**
 *  OpenGL messages buffer.
 */
GLchar Shader::message_buffer[GL_INFO_LOG_LENGTH] { 0 };

/**
 *  Some shader sources.
 */
// basic vertex shader -- care about vertex position
const std::string Shader::vs_basic = GLSL(130,
    uniform mat4 mvp_matrix;
    in vec3 vertex_position;

    void main (void) {
        gl_Position = mvp_matrix * vec4(vertex_position, 1);
    }
);

// basic fragment shader -- care about fragment color (from uniform)
const std::string Shader::fs_basic_color_uniform = GLSL(130,
    uniform vec4 uniform_color;
    out vec4 fragment_color;

    void main (void) {
        fragment_color = uniform_color;
    }
);

// basic vertex shader -- care about vertex position and color
const std::string Shader::vs_basic_attribute_color = GLSL(130,
    uniform mat4 mvp_matrix;
    in vec3 vertex_position;
    in vec4 vertex_color;
    smooth out vec4 vertex_fragment_color;

    void main (void) {
        vertex_fragment_color = vertex_color;
        gl_Position = mvp_matrix * vec4(vertex_position, 1);
    }
);

// basic fragment shader -- care about fragment color (from vs)
const std::string Shader::fs_basic_color_in = GLSL(130,
    smooth in vec4 vertex_fragment_color;
    out vec4 fragment_color;

    void main (void) {
        fragment_color = vertex_fragment_color;
    }
);

// all attrib vertex shader
const std::string Shader::vs_all_attrib = GLSL(130,
    precision highp float;

    in vec3 vert_position;
    in vec3 vert_normal;
    in vec2 vert_uv;

    uniform mat4 mv_matrix;
    uniform mat4 p_matrix;

    smooth out vec3 frag_normal;
    smooth out vec3 frag_position;
    smooth out vec3 frag_mv_position;

    vec4 mv_position = mv_matrix * vec4(vert_position, 1);
    mat3 normal_matrix;

    void main (void) {
        normal_matrix[0] = mv_matrix[0].xyz;
        normal_matrix[1] = mv_matrix[1].xyz;
        normal_matrix[2] = mv_matrix[2].xyz;

        frag_position = vert_position;
        frag_mv_position = mv_position.xyz;
        frag_normal = normalize(normal_matrix * vert_normal);

        gl_Position = p_matrix * mv_position;
    }
);

// all attrib fragment shader
const std::string Shader::fs_all_attrib = GLSL(130,
    precision highp float;

    uniform vec4 color;
    uniform vec3 light_direction;

    smooth in vec3 frag_position;
    smooth in vec3 frag_mv_position;
    smooth in vec3 frag_normal;

    out vec4 out_color;

    // void main (void) {
    //     // mix position and normal as color
    //     // out_color = vec4(
    //     //     mix(
    //     //         normalize(abs(frag_position)),
    //     //         frag_normal,
    //     //         0.5
    //     //     ), 1
    //     // );

    //     // simple directional light
    //     out_color.rgb =
    //         color.rgb * max(0.0, dot(frag_normal, light_direction));
    //     out_color.a = color.a;
    // }

    vec3 phong_blinn_edge_directional (
        vec3 direction, float intensity,
        float ambient, float diffuse, float specular, float shininess
    ) {
        vec3 s = normalize(direction);
        vec3 v = normalize(-frag_mv_position);
        vec3 normal = normalize(frag_normal);
        vec3 h = normalize(v + s);
        float edge = 1.0 - abs(dot(v, normal));
        return vec3(
            ambient + diffuse * intensity * max(0.0, dot(normal, s)),
            specular * pow(max(0.0, dot(normal, h)), shininess),
            edge*edge
        );
    }

    // vec3 rim_light (vec3 color, float start, float end, float coef) {
    //   vec3 normal = normalize(frag_normal);
    //   vec3 eye = normalize(-frag_mv_position.xyz);
    //   float rim = smoothstep(start, end, 1.0 - dot(normal, eye));
    //   return clamp(rim, 0.0, 1.0) * coef * color;
    // }

    void main () {
        vec3 params = phong_blinn_edge_directional(
            light_direction, 4.0,
            0.1, 0.2, 0.8, 256.0
        );
        out_color.rgb = clamp(
            params.x * color.rgb + params.y * color.rgb - vec3(params.z*0.1),
            0, 1
        );
        out_color.a = color.a;
    }
);

/**
 *  Initialization with attribute binding.
 *  Example invocation:
 *      Shader some_shader {
 *          shader::vs_basic,
 *          shader::fs_basic, {
 *              std::make_tuple(
 *                  "vertex_position", Shader::attrib_index::vertex
 *              )
 *      } };
 */
Shader::Shader (
    const std::string &vs, const std::string &fs,
    const std::initializer_list<
        std::tuple<std::string, Shader::attrib_index>
    > binding
) throw (std::runtime_error) {
    // temporary shader objects (load and compile from sources)
    GLuint
        vertex_shader { this->load_shader(GL_VERTEX_SHADER, vs) },
        fragment_shader { this->load_shader(GL_FRAGMENT_SHADER, fs) };

    // status variable (for testing errors)
    GLint status;

    // attach shaders to gl program
    this->program = glCreateProgram();
    glAttachShader(this->program, vertex_shader);
    glAttachShader(this->program, fragment_shader);

    // bind attributes to the gl program
    for (auto it = binding.begin();  it != binding.end();  it++) {
        glBindAttribLocation(
            this->program,
            std::get<1>(*it),
            std::get<0>(*it).data()
        );
    }

    // link gl program
    glLinkProgram(this->program);

    // temporary shaders are no longer needed
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);

    // check for link errors
    glGetProgramiv(this->program, GL_LINK_STATUS, &status);
    if (status == GL_FALSE) {
        std::string error_message {
            this->get_program_info_log(this->program)
        };
        glDeleteProgram(this->program);
        throw std::runtime_error(error_message);
    }
}

/**
 *  Clean-up.
 */
Shader::~Shader () {
    if (this->program != 0) {
        glDeleteProgram(this->program);
        this->program = 0;
    }
}

/**
 *  Assign uniforms and use shader.
 *  Example invocation:
 *      some_shader.use({
 *          std::make_tuple("mvp_matrix", [&] (GLuint location) {
 *              glUniformMatrix4fv(location, 1, GL_FALSE, *mvp_matrix);
 *          })
 *      });
 */
const Shader& Shader::use (
    std::initializer_list<
        std::tuple<std::string, std::function<void (GLint)>>
    > uniforms
) const {
    glUseProgram(this->program);

    for (auto it = uniforms.begin();  it != uniforms.end();  it++) {
        std::get<1>(*it)(
            glGetUniformLocation(
                this->program, (GLchar*)std::get<0>(*it).data()
            )
        );
    }

    return *this;
}

/**
 *  Compile shader from a given source.
 */
GLuint Shader::load_shader (
    GLenum shader_type,
    const std::string &shader_src
) throw (std::runtime_error) {
    GLuint shader { glCreateShader(shader_type) };
    const GLchar *src { (GLchar*)shader_src.data() };
    GLint status;

    glShaderSource(shader, 1, &src, NULL);
    glCompileShader(shader);
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if (status == GL_FALSE) {
        std::string error_message {
            this->get_shader_info_log(shader)
        };
        glDeleteShader(shader);
        throw std::runtime_error(error_message);
    }

    return shader;
}

/**
 *  Get shader compilation log message.
 */
std::string Shader::get_shader_info_log (GLuint shader) {
    glGetShaderInfoLog(
        shader, GL_INFO_LOG_LENGTH, NULL, Shader::message_buffer
    );
    return "GLSL shader: " + std::string(Shader::message_buffer);
}

/**
 *  Get program linking log.
 */
std::string Shader::get_program_info_log (GLuint program) {
    glGetProgramInfoLog(
        program, GL_INFO_LOG_LENGTH, NULL, Shader::message_buffer
    );
    return "GLSL program: " + std::string(Shader::message_buffer);
}

} // namespace machina

#endif
<|endoftext|>