<commit_before>
#include <cstring>
#include <algorithm>

#include "Furigana.h"
#include "Utf8.h"

std::unordered_map<uint32_t, uint32_t> Furigana::KataToHiraTable;

const char Furigana::katakanas[][4] = {
    "ァ","ア","ィ","イ","ゥ","ウ","ェ","エ","ォ","オ",
    "カ","ガ","キ","ギ","ク","グ","ケ","ゲ","コ","ゴ",
    "サ","ザ","シ","ジ","ス","ズ","セ","ゼ","ソ","ゾ",
    "タ","ダ","チ","ヂ","ッ","ツ","ヅ","テ","デ","ト",
    "ド","ナ","ニ","ヌ","ネ","ノ","ハ","バ","パ","ヒ",
    "ビ","ピ","フ","ブ","プ","ヘ","ベ","ペ","ホ","ボ",
    "ポ","マ","ミ","ム","メ","モ","ャ","ヤ","ュ","ユ",
    "ョ","ヨ","ラ","リ","ル","レ","ロ","ヮ","ワ","ヲ",
    "ン","ヴ","ヵ","ヶ"
};

const char Furigana::hiraganas[][4] = {
    "ぁ","あ","ぃ","い","ぅ","う","ぇ","え","ぉ","お",
    "か","が","き","ぎ","く","ぐ","け","げ","こ","ご",
    "さ","ざ","し","じ","す","ず","せ","ぜ","そ","ぞ",
    "た","だ","ち","ぢ","っ","つ","づ","て","で","と",
    "ど","な","に","ぬ","ね","の","は","ば","ぱ","ひ",
    "び","ぴ","ふ","ぶ","ぷ","へ","べ","ぺ","ほ","ぼ",
    "ぽ","ま","み","む","め","も","ゃ","や","ゅ","ゆ",
    "ょ","よ","ら","り","る","れ","ろ","ゎ","わ","を",
    "ん","ゔ","ゕ","ゖ"
};

Furigana::Furigana() {
    /* Initialize the katakana to hiragana hash table. */
    static size_t numKanas = sizeof(Furigana::katakanas)/sizeof(Furigana::katakanas[0]);
    for (int i = 0; i < numKanas; i++) {
        uint32_t katakana = *(uint32_t*)Furigana::katakanas[i];
        uint32_t hiragana = *(uint32_t*)Furigana::hiraganas[i];
        Furigana::KataToHiraTable.insert(std::make_pair(katakana, hiragana));
    }
}

/**
 * Return the given string with katakanas converted
 * to their hiragana equivalents.
 */
std::string Furigana::katakana_to_hiragana(std::string katakana)
{
    const char *str = katakana.c_str();
    char character[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */
    std::string hiraganas;

    while (utf8_getc(&str, character, sizeof(character)-1)) {
        auto res = Furigana::KataToHiraTable.find(*(uint32_t*)character);
        if (res != Furigana::KataToHiraTable.end()) {
            std::memcpy(character, &res->second, sizeof(character)-1);
        }

        hiraganas.append(character, std::strlen(character));
    }

    return hiraganas;
}

static inline void remove_spaces(std::string &str)
{
    str.erase(
        std::remove_if(
            str.begin(),
            str.end(),
            (int(*)(int))std::isspace),
        str.end()
    );
}

/**
 * Given two strings, check if they start with the same characters. If so,
 * return the length (in bytes) of equal part, or zero otherwise.
 * Return zero if the strings are equal.
 */
static size_t find_initial_equal_chars(char *kanjis_start, char *reading_start)
{
    const char *kanjis  = (const char*) kanjis_start;
    const char *reading = (const char*) reading_start;
    const char *kanjis_prev;
    char kanji_char[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */
    char  kana_char[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */

    if (strcmp(kanjis, reading) == 0) {
        return 0;
    }

    while (true) {
        kanjis_prev = kanjis;
        int more_kanjis  = utf8_getc(&kanjis, kanji_char, sizeof(kanji_char)-1);
        int more_reading = utf8_getc(&reading, kana_char, sizeof(kana_char)-1);
        if (!more_kanjis || !more_reading ||
            strncmp(kanji_char, kana_char, sizeof(kanji_char)) != 0) {
            break;
        }
    }
    return kanjis_prev - kanjis_start;
}

/**
 * Find how much we should trim the given reading and kanji strings.
 * Returns the length of head and tail to trim.
 */
static void find_trim_boundaries(
    std::string kanjis_std,
    std::string reading_std,
    size_t *start_len,
    size_t *end_len
) {
    char *kanjis  = strdup(kanjis_std.c_str());
    char *reading = strdup(reading_std.c_str());

    *start_len = find_initial_equal_chars(kanjis, reading);
    utf8_strrev(kanjis);
    utf8_strrev(reading);
    *end_len = find_initial_equal_chars(kanjis, reading);
    free(kanjis);
    free(reading);
}

/**
 * Split the given strings into one, two, or three parts, giving the
 * provided head and tail length.
 */
static std::vector<std::pair<std::string, std::string> > split_furigana(
    std::string kanjisString,
    std::string readingString,
    int start_len,
    int end_len
) {
    std::vector<std::pair<std::string, std::string> > tokens;
    tokens.push_back(std::pair<std::string, std::string>(
        kanjisString.substr(
            start_len, kanjisString.length() - end_len - start_len
        ),
        readingString.substr(
            start_len, readingString.length() - end_len - start_len
        )
    ));
    if (start_len > 0) {
        tokens.insert(
            tokens.begin(),
            std::pair<std::string, std::string>(
                kanjisString.substr(0, start_len),
                readingString.substr(0, start_len)
            )
        );
    }
    if (end_len > 0) {
        tokens.push_back(std::pair<std::string, std::string>(
            kanjisString.substr(kanjisString.length() - end_len),
            readingString.substr(readingString.length() - end_len)
        ));
    }
    return tokens;
}

/**
 * Removes useless furiganas at the beginning and at the end.
 */
std::vector<std::pair<std::string, std::string> > Furigana::tokenize(
    std::string kanjisString,
    std::string readingString
) {
    size_t start_len, end_len;

    remove_spaces(readingString);
    readingString = this->katakana_to_hiragana(readingString);
    find_trim_boundaries(
        this->katakana_to_hiragana(kanjisString),
        readingString,
        &start_len,
        &end_len
    );

    auto tokens = split_furigana(
        kanjisString,
        readingString,
        start_len,
        end_len
    );

    for (auto& text : tokens) {
        if (this->katakana_to_hiragana(text.first) == text.second) {
            text.second = "";
        }
    }

    return tokens;
}
<commit_msg>Split furigana on markers and remove trimming<commit_after>
#include <cstring>
#include <algorithm>

#include "Furigana.h"
#include "Utf8.h"

#define WARIFURI_SEPARATOR '.'

std::unordered_map<uint32_t, uint32_t> Furigana::KataToHiraTable;

const char Furigana::katakanas[][4] = {
    "ァ","ア","ィ","イ","ゥ","ウ","ェ","エ","ォ","オ",
    "カ","ガ","キ","ギ","ク","グ","ケ","ゲ","コ","ゴ",
    "サ","ザ","シ","ジ","ス","ズ","セ","ゼ","ソ","ゾ",
    "タ","ダ","チ","ヂ","ッ","ツ","ヅ","テ","デ","ト",
    "ド","ナ","ニ","ヌ","ネ","ノ","ハ","バ","パ","ヒ",
    "ビ","ピ","フ","ブ","プ","ヘ","ベ","ペ","ホ","ボ",
    "ポ","マ","ミ","ム","メ","モ","ャ","ヤ","ュ","ユ",
    "ョ","ヨ","ラ","リ","ル","レ","ロ","ヮ","ワ","ヲ",
    "ン","ヴ","ヵ","ヶ"
};

const char Furigana::hiraganas[][4] = {
    "ぁ","あ","ぃ","い","ぅ","う","ぇ","え","ぉ","お",
    "か","が","き","ぎ","く","ぐ","け","げ","こ","ご",
    "さ","ざ","し","じ","す","ず","せ","ぜ","そ","ぞ",
    "た","だ","ち","ぢ","っ","つ","づ","て","で","と",
    "ど","な","に","ぬ","ね","の","は","ば","ぱ","ひ",
    "び","ぴ","ふ","ぶ","ぷ","へ","べ","ぺ","ほ","ぼ",
    "ぽ","ま","み","む","め","も","ゃ","や","ゅ","ゆ",
    "ょ","よ","ら","り","る","れ","ろ","ゎ","わ","を",
    "ん","ゔ","ゕ","ゖ"
};

Furigana::Furigana() {
    /* Initialize the katakana to hiragana hash table. */
    static size_t numKanas = sizeof(Furigana::katakanas)/sizeof(Furigana::katakanas[0]);
    for (int i = 0; i < numKanas; i++) {
        uint32_t katakana = *(uint32_t*)Furigana::katakanas[i];
        uint32_t hiragana = *(uint32_t*)Furigana::hiraganas[i];
        Furigana::KataToHiraTable.insert(std::make_pair(katakana, hiragana));
    }
}

/**
 * Return the given string with katakanas converted
 * to their hiragana equivalents.
 */
std::string Furigana::katakana_to_hiragana(std::string katakana)
{
    const char *str = katakana.c_str();
    char character[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */
    std::string hiraganas;

    while (utf8_getc(&str, character, sizeof(character)-1)) {
        auto res = Furigana::KataToHiraTable.find(*(uint32_t*)character);
        if (res != Furigana::KataToHiraTable.end()) {
            std::memcpy(character, &res->second, sizeof(character)-1);
        }

        hiraganas.append(character, std::strlen(character));
    }

    return hiraganas;
}

static inline void remove_spaces(std::string &str)
{
    str.erase(
        std::remove_if(
            str.begin(),
            str.end(),
            (int(*)(int))std::isspace),
        str.end()
    );
}

/**
 * Given two strings, check if they start with the same characters. If so,
 * return the length (in bytes) of equal part, or zero otherwise.
 * Return zero if the strings are equal.
 */
static size_t find_initial_equal_chars(char *kanjis_start, char *reading_start)
{
    const char *kanjis  = (const char*) kanjis_start;
    const char *reading = (const char*) reading_start;
    const char *kanjis_prev;
    char kanji_char[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */
    char  kana_char[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */

    if (strcmp(kanjis, reading) == 0) {
        return 0;
    }

    while (true) {
        kanjis_prev = kanjis;
        int more_kanjis  = utf8_getc(&kanjis, kanji_char, sizeof(kanji_char)-1);
        int more_reading = utf8_getc(&reading, kana_char, sizeof(kana_char)-1);
        if (!more_kanjis || !more_reading ||
            strncmp(kanji_char, kana_char, sizeof(kanji_char)) != 0) {
            break;
        }
    }
    return kanjis_prev - kanjis_start;
}

/**
 * Split the given string into one or more parts,
 * giving the provided separator character.
 * Each token in readingString matches one char of kanjisString.
 * Several consecutive separator characters means the token
 * spans on multiple chars of kanjisString.
 */
static std::vector<std::pair<std::string, std::string> > split_furigana(
    std::string kanjisString,
    std::string readingString,
    const char separator
) {
    std::vector<std::pair<std::string, std::string> > tokens;
    const char *kanjis = kanjisString.c_str();
    std::size_t reading_start = 0, reading_end = 0;
    char kanji_char[5] = { '\0' }; /* 4 UTF-8 bytes + '\0' = 5 */

    while (true) {
        int more_kanjis = utf8_getc(&kanjis, kanji_char, sizeof(kanji_char)-1);
        std::string kanji_chars(kanji_char);
        reading_end = readingString.find(separator, reading_start);
        std::string reading_chars
            = readingString.substr(reading_start, reading_end - reading_start);

        /* Consecutive separators: the reading spans on the previous kanji */
        if (reading_start == reading_end) {
            kanji_chars = tokens.back().first + kanji_chars;
            reading_chars = tokens.back().second;
            tokens.pop_back();
        }

        /* Stuff the remaining kanjis if we reached the end of the readings */
        if (reading_end == std::string::npos && more_kanjis) {
            while (more_kanjis = utf8_getc(&kanjis, kanji_char,
                                           sizeof(kanji_char)-1)) {
                kanji_chars += kanji_char;
            }
        }

        tokens.push_back(std::pair<std::string, std::string>(
            kanji_chars,
            reading_chars
        ));
        if (!more_kanjis || reading_end == std::string::npos) {
            break;
        }
        reading_start = reading_end + 1;
    }
    return tokens;
}

/**
 * Removes useless furiganas at the beginning and at the end.
 */
std::vector<std::pair<std::string, std::string> > Furigana::tokenize(
    std::string kanjisString,
    std::string readingString
) {
    size_t start_len, end_len;

    remove_spaces(readingString);
    readingString = this->katakana_to_hiragana(readingString);

    auto tokens = split_furigana(
        kanjisString,
        readingString,
        WARIFURI_SEPARATOR
    );

    for (auto& text : tokens) {
        if (this->katakana_to_hiragana(text.first) == text.second) {
            text.second = "";
        }
    }

    return tokens;
}
<|endoftext|>


<commit_before>#include "Geometry.h"

#include <math.h>

#include "Logger.h"

/*static*/ std::unique_ptr<Geometry>
Geometry::Sphere(int sectors, int rings, float radius, bool genNormals, bool genTangents, bool genTexCoords)
{
	if (genTangents)
	{
		Logger::Log("Error: tried to generate a sphere with tangents, which is not implemented! Ignoring instruction.");

		if (!(genNormals && genTexCoords))
		{
			Logger::Log("Error: tried to generate a sphere with tangents but without tex-coords and normals, which is not possible!");
			return nullptr;
		}
	}

	std::unique_ptr<Geometry> sphere{ new Geometry() };

	sphere->positions.resize(rings * sectors * 3);
	if (genNormals) sphere->normals.resize(rings * sectors * 3);
	if (genTangents) sphere->tangents.resize(rings * sectors * 3);
	if (genTexCoords) sphere->texCoords.resize(rings * sectors * 2);

	auto p = sphere->positions.begin();
	auto n = sphere->normals.begin();
	auto t = sphere->tangents.begin();
	auto tex = sphere->texCoords.begin();

	float const R = 1.0f / (float)(rings-1);
	float const S = 1.0f / (float)(sectors-1);

	for(int r = 0; r < rings; r++)
	{
		for(int s = 0; s < sectors; s++)
		{
			const float y = sinf( -M_PI_2 + M_PI * r * R );
			const float x = cosf(2*M_PI * s * S) * sin( M_PI * r * R );
			const float z = sinf(2*M_PI * s * S) * sin( M_PI * r * R );

			*p++ = x * radius;
			*p++ = y * radius;
			*p++ = z * radius;

			if (genNormals)
			{
				*n++ = x;
				*n++ = y;
				*n++ = z;
			}

			if (genTangents)
			{
				// TODO: Implement!
				*t++ = 0.0f;
				*t++ = 0.0f;
				*t++ = 0.0f;
			}

			if (genTexCoords)
			{
				*tex++ = s * S;
				*tex++ = r * R;
			}
		}
	}

	sphere->indices.resize(rings * sectors * 6); // resize for triangles
	std::vector<unsigned int>::iterator i = sphere->indices.begin();
	for(int r = 0; r < rings - 1; ++r)
	{
		for(int s = 0; s < sectors - 1; ++s)
		{
			const int i0 = r * sectors + s;
			const int i1 = r * sectors + (s + 1);
			const int i2 = (r + 1) * sectors + (s + 1);
			const int i3 = (r + 1) * sectors + s;

			// Triangles
			*i++ = i0;
			*i++ = i1;
			*i++ = i2;

			*i++ = i0;
			*i++ = i2;
			*i++ = i3;

			// Quads
			//*i++ = i0;
			//*i++ = i1;
			//*i++ = i2;
			//*i++ = i3;
		}
	}

	return sphere;
}
<commit_msg>Fix winding order for generated sphere geometry<commit_after>#include "Geometry.h"

#include <math.h>

#include "Logger.h"

/*static*/ std::unique_ptr<Geometry>
Geometry::Sphere(int sectors, int rings, float radius, bool genNormals, bool genTangents, bool genTexCoords)
{
	if (genTangents)
	{
		Logger::Log("Error: tried to generate a sphere with tangents, which is not implemented! Ignoring instruction.");

		if (!(genNormals && genTexCoords))
		{
			Logger::Log("Error: tried to generate a sphere with tangents but without tex-coords and normals, which is not possible!");
			return nullptr;
		}
	}

	std::unique_ptr<Geometry> sphere{ new Geometry() };

	sphere->positions.resize(rings * sectors * 3);
	if (genNormals) sphere->normals.resize(rings * sectors * 3);
	if (genTangents) sphere->tangents.resize(rings * sectors * 3);
	if (genTexCoords) sphere->texCoords.resize(rings * sectors * 2);

	auto p = sphere->positions.begin();
	auto n = sphere->normals.begin();
	auto t = sphere->tangents.begin();
	auto tex = sphere->texCoords.begin();

	float const R = 1.0f / (float)(rings-1);
	float const S = 1.0f / (float)(sectors-1);

	for(int r = 0; r < rings; r++)
	{
		for(int s = 0; s < sectors; s++)
		{
			const float y = sinf( -M_PI_2 + M_PI * r * R );
			const float x = cosf(2*M_PI * s * S) * sin( M_PI * r * R );
			const float z = sinf(2*M_PI * s * S) * sin( M_PI * r * R );

			*p++ = x * radius;
			*p++ = y * radius;
			*p++ = z * radius;

			if (genNormals)
			{
				*n++ = x;
				*n++ = y;
				*n++ = z;
			}

			if (genTangents)
			{
				// TODO: Implement!
				*t++ = 0.0f;
				*t++ = 0.0f;
				*t++ = 0.0f;
			}

			if (genTexCoords)
			{
				*tex++ = s * S;
				*tex++ = r * R;
			}
		}
	}

	sphere->indices.resize(rings * sectors * 6); // resize for triangles
	std::vector<unsigned int>::iterator i = sphere->indices.begin();
	for(int r = 0; r < rings - 1; ++r)
	{
		for(int s = 0; s < sectors - 1; ++s)
		{
			const int i0 = r * sectors + s;
			const int i1 = r * sectors + (s + 1);
			const int i2 = (r + 1) * sectors + (s + 1);
			const int i3 = (r + 1) * sectors + s;

			// Triangles
			*i++ = i2;
			*i++ = i1;
			*i++ = i0;

			*i++ = i3;
			*i++ = i2;
			*i++ = i0;

			// Quads
			//*i++ = i0;
			//*i++ = i1;
			//*i++ = i2;
			//*i++ = i3;
		}
	}

	return sphere;
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            flushDrawCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context, error: " << eglGetError();
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface, error: " << eglGetError();
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display, error: " << eglGetError();
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL, error: " << eglGetError();
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config, error: " << eglGetError();
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API, error: " << eglGetError();
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface, error: " << eglGetError();
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval, error: " << eglGetError();
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers, error: " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                return false;
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<commit_msg>Remove the unneeded return<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/CompileConfig.h"

#if OUZEL_PLATFORM_RASPBIAN && OUZEL_SUPPORTS_OPENGL

#include "RendererOGLRasp.h"
#include "core/Engine.h"
#include "core/raspbian/WindowRasp.h"
#include "utils/Log.h"

namespace ouzel
{
    namespace graphics
    {
        RendererOGLRasp::RendererOGLRasp():
            running(false)
        {
        }

        RendererOGLRasp::~RendererOGLRasp()
        {
            running = false;
            flushDrawCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context, error: " << eglGetError();
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface, error: " << eglGetError();
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RendererOGLRasp::init(Window* newWindow,
                                   const Size2& newSize,
                                   uint32_t newSampleCount,
                                   Texture::Filter newTextureFilter,
                                   uint32_t newMaxAnisotropy,
                                   bool newVerticalSync,
                                   bool newDepth,
                                   bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display, error: " << eglGetError();
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL, error: " << eglGetError();
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config, error: " << eglGetError();
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API, error: " << eglGetError();
                return false;
            }

            uint32_t width = static_cast<uint32_t>(newSize.v[0]);
            uint32_t height = static_cast<uint32_t>(newSize.v[1]);

            VC_RECT_T dstRect;
            dstRect.x = 0;
            dstRect.y = 0;
            dstRect.width = width;
            dstRect.height = height;

            VC_RECT_T srcRect;
            srcRect.x = 0;
            srcRect.y = 0;
            srcRect.width = width;
            srcRect.height = height;

            DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
            DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0);

            DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate, dispmanDisplay,
                        0, &dstRect, 0,
                        &srcRect, DISPMANX_PROTECTION_NONE,
                        0, 0, DISPMANX_NO_ROTATE);

            nativewindow.element = dispmanElement;
            nativewindow.width = width;
            nativewindow.height = height;
            vc_dispmanx_update_submit_sync(dispmanUpdate);

            surface = eglCreateWindowSurface(display, config, reinterpret_cast<EGLNativeWindowType>(&nativewindow), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface, error: " << eglGetError();
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval, error: " << eglGetError();
                return false;
            }

            if (!RendererOGL::init(newWindow,
                                   newSize,
                                   newSampleCount,
                                   newTextureFilter,
                                   newMaxAnisotropy,
                                   newVerticalSync,
                                   newDepth,
                                   newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
                return false;
            }

            running = true;
            renderThread = std::thread(&RendererOGLRasp::main, this);

            return true;
        }

        bool RendererOGLRasp::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            return true;
        }

        bool RendererOGLRasp::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers, error: " << eglGetError();
                return false;
            }

            return true;
        }

        void RendererOGLRasp::main()
        {
            while (running)
            {
                process();
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>// Copyright 2021 MozoLM Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Basic authentication end-to-end tests.

#include <filesystem>
#include <string>

#include "gmock/gmock.h"
#include "mozolm/stubs/status-matchers.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mozolm/grpc/auth_test_utils.h"
#include "mozolm/grpc/client_helper.h"
#include "mozolm/grpc/server_helper.h"
#include "mozolm/utils/file_util.h"
#include "mozolm/stubs/status_macros.h"

namespace mozolm {
namespace grpc {
namespace {

const char kModelsTestDir[] =
    "mozolm/models/testdata";
const char kCharFstModelFilename[] = "gutenberg_en_char_ngram_o2_kn.fst";
const char kUdsEndpointName[] = "auth_end2end_test.sock";
constexpr double kClientTimeoutSec = 1.0;

// The test fixtures are currently parametrized by the socket type (UDS/TCP).
class AuthEnd2EndTest : public ::testing::TestWithParam<bool>  {
 protected:
  void SetUp() override {
    test::ReadAllSslCredentials(&ssl_name2contents_);
  }

  void TearDown() override {
    // Clean up UDS, if configured.
    if (!uds_path_.empty() && std::filesystem::exists(uds_path_)) {
      EXPECT_TRUE(std::filesystem::remove(uds_path_));
    }
  }

  // Given the configuration, builds and starts the server. Then builds the
  // client and attempts to speak to the server.
  absl::Status BuildAndRun(const ClientConfig &config) const {
    // Initialize and start the server.
    ServerHelper server;
    RETURN_IF_ERROR(server.Init(config_.server()));
    RETURN_IF_ERROR((server.Run(/* wait_till_terminated= */false)));

    // Initialize and start the client.
    ClientConfig current_config = config;
    InitConfigDefaults(&current_config);
    if (uds_path_.empty()) {  // Not using UDS.
      const int server_port = server.server().selected_port();
      EXPECT_LT(0, server_port) << "Invalid port: " << server_port;
      current_config.mutable_server()->set_address_uri(
          absl::StrCat("localhost:", server_port));
    }
    ClientHelper client;
    RETURN_IF_ERROR(client.Init(current_config));

    // Send one random generation request.
    std::string result;
    RETURN_IF_ERROR(client.RandGen(/* context_string= */"", &result));
    EXPECT_FALSE(result.empty());
    return absl::OkStatus();
  }

  // Initializes core server and client configuration. Enabling `use_uds` will
  // configure the UNIX Domain socket (UDS) endpoint, otherwise regular TCP
  // sockets are used.
  void InitConfig(ClientConfig *config, bool use_uds) {
    // Initialize server part.
    ServerConfig *server_config = config->mutable_server();
    if (use_uds) {
      uds_path_ = file::TempFilePath(kUdsEndpointName);
      server_config->set_address_uri(absl::StrCat("unix://", uds_path_));
    } else {
      server_config->set_address_uri("localhost:0");
    }
    server_config->set_wait_for_clients(false);
    auto *model = server_config->mutable_model_hub_config()->add_model_config();
    model->set_type(ModelConfig::CHAR_NGRAM_FST);
    model->mutable_storage()->set_model_file(
        ModelPath(kModelsTestDir, kCharFstModelFilename));

    // Initialize the client part.
    config->set_timeout_sec(kClientTimeoutSec);
  }

  // Fills in server SSL config.
  void MakeServerSslConfig(ServerConfig *config, bool verify_clients) {
    ServerAuthConfig *auth = config->mutable_auth();
    auth->set_credential_type(CREDENTIAL_SSL);
    auth->mutable_ssl()->set_client_verify(verify_clients);
    auth->mutable_ssl()->set_server_key(
        ssl_name2contents_[test::kSslServerPrivateKeyFile]);
    auth->mutable_ssl()->set_server_cert(
        ssl_name2contents_[test::kSslServerPublicCertFile]);
  }

  // Returns full path to the model.
  std::string ModelPath(std::string_view model_dir,
                        std::string_view model_filename) const {
    const std::filesystem::path model_path = (
        std::filesystem::current_path() /
        model_dir / model_filename).make_preferred();
    return model_path.string();
  }

  // Mapping between the names of SSL credential files and the actual contents.
  absl::flat_hash_map<std::string, std::string> ssl_name2contents_;

  // Global configuration (this includes both client and the server).
  ClientConfig config_;

  // UNIX Domain Socket (UDS) path.
  std::string uds_path_;
};

// Check insecure credentials.
TEST_P(AuthEnd2EndTest, CheckInsecure) {
  InitConfig(&config_, /* use_uds= */GetParam());
  EXPECT_OK(BuildAndRun(config_));
}

// The certificate presented by the client is not checked by the server at all.
TEST_P(AuthEnd2EndTest, CheckSslNoClientVerification) {
  InitConfig(&config_, /* use_uds= */GetParam());

  // Prepare the server credentials and run insecure client.
  MakeServerSslConfig(config_.mutable_server(), /* verify_clients= */false);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Prepare the client credentials by setting the target name. Will use the
  // server public certificate authority from the server config.
  ClientAuthConfig *auth = config_.mutable_auth();
  auth->mutable_ssl()->set_target_name_override(test::kSslAltServerName);
  EXPECT_OK(BuildAndRun(config_));
}

// Mutual SSL/TLS verification: server requests client certificate and enforces
// that the client presents a certificate. This uses Certificate Authority (CA).
TEST_P(AuthEnd2EndTest, CheckSslWithClientVerification) {
  InitConfig(&config_, /* use_uds= */GetParam());

  // Prepare the server credentials and run insecure client.
  MakeServerSslConfig(config_.mutable_server(), /* verify_clients= */true);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Check that correctly setting target name override is not enough as client
  // does not present any credentials.
  ClientAuthConfig::SslConfig *client_ssl =
      config_.mutable_auth()->mutable_ssl();
  client_ssl->set_target_name_override(test::kSslAltServerName);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Set up all the required certificates and keys. The server certificate and
  // key are already set up. Check successful handshake and run.
  ServerAuthConfig *server_auth = config_.mutable_server()->mutable_auth();
  server_auth->mutable_ssl()->set_custom_ca_cert(
      ssl_name2contents_[test::kSslClientCentralAuthCertFile]);
  client_ssl->set_client_cert(
      ssl_name2contents_[test::kSslClientPublicCertFile]);
  client_ssl->set_client_key(
      ssl_name2contents_[test::kSslClientPrivateKeyFile]);
  EXPECT_OK(BuildAndRun(config_));
}

INSTANTIATE_TEST_SUITE_P(
    AuthEnd2EndTestSuite, AuthEnd2EndTest,
    // Use UNIX Domain Sockets (UDS) or the default TCP sockets.
    ::testing::Values(false, true));

}  // namespace
}  // namespace grpc
}  // namespace mozolm
<commit_msg>Disable UDS test on Windows. UDS is only supported in new Windows versions.<commit_after>// Copyright 2021 MozoLM Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Basic authentication end-to-end tests.

#include <filesystem>
#include <string>

#include "gmock/gmock.h"
#include "mozolm/stubs/status-matchers.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "mozolm/grpc/auth_test_utils.h"
#include "mozolm/grpc/client_helper.h"
#include "mozolm/grpc/server_helper.h"
#include "mozolm/utils/file_util.h"
#include "mozolm/stubs/status_macros.h"

namespace mozolm {
namespace grpc {
namespace {

const char kModelsTestDir[] =
    "mozolm/models/testdata";
const char kCharFstModelFilename[] = "gutenberg_en_char_ngram_o2_kn.fst";
const char kUdsEndpointName[] = "auth_end2end_test.sock";
constexpr double kClientTimeoutSec = 1.0;

// The test fixtures are currently parametrized by the socket type (UDS/TCP).
class AuthEnd2EndTest : public ::testing::TestWithParam<bool>  {
 protected:
  void SetUp() override {
    test::ReadAllSslCredentials(&ssl_name2contents_);
  }

  void TearDown() override {
    // Clean up UDS, if configured.
    if (!uds_path_.empty() && std::filesystem::exists(uds_path_)) {
      EXPECT_TRUE(std::filesystem::remove(uds_path_));
    }
  }

  // Given the configuration, builds and starts the server. Then builds the
  // client and attempts to speak to the server.
  absl::Status BuildAndRun(const ClientConfig &config) const {
    // Initialize and start the server.
    ServerHelper server;
    RETURN_IF_ERROR(server.Init(config_.server()));
    RETURN_IF_ERROR((server.Run(/* wait_till_terminated= */false)));

    // Initialize and start the client.
    ClientConfig current_config = config;
    InitConfigDefaults(&current_config);
    if (uds_path_.empty()) {  // Not using UDS.
      const int server_port = server.server().selected_port();
      EXPECT_LT(0, server_port) << "Invalid port: " << server_port;
      current_config.mutable_server()->set_address_uri(
          absl::StrCat("localhost:", server_port));
    }
    ClientHelper client;
    RETURN_IF_ERROR(client.Init(current_config));

    // Send one random generation request.
    std::string result;
    RETURN_IF_ERROR(client.RandGen(/* context_string= */"", &result));
    EXPECT_FALSE(result.empty());
    return absl::OkStatus();
  }

  // Initializes core server and client configuration. Enabling `use_uds` will
  // configure the UNIX Domain socket (UDS) endpoint, otherwise regular TCP
  // sockets are used.
  void InitConfig(ClientConfig *config, bool use_uds) {
    // Initialize server part.
    ServerConfig *server_config = config->mutable_server();
    if (use_uds) {
      uds_path_ = file::TempFilePath(kUdsEndpointName);
      server_config->set_address_uri(absl::StrCat("unix://", uds_path_));
    } else {
      server_config->set_address_uri("localhost:0");
    }
    server_config->set_wait_for_clients(false);
    auto *model = server_config->mutable_model_hub_config()->add_model_config();
    model->set_type(ModelConfig::CHAR_NGRAM_FST);
    model->mutable_storage()->set_model_file(
        ModelPath(kModelsTestDir, kCharFstModelFilename));

    // Initialize the client part.
    config->set_timeout_sec(kClientTimeoutSec);
  }

  // Fills in server SSL config.
  void MakeServerSslConfig(ServerConfig *config, bool verify_clients) {
    ServerAuthConfig *auth = config->mutable_auth();
    auth->set_credential_type(CREDENTIAL_SSL);
    auth->mutable_ssl()->set_client_verify(verify_clients);
    auth->mutable_ssl()->set_server_key(
        ssl_name2contents_[test::kSslServerPrivateKeyFile]);
    auth->mutable_ssl()->set_server_cert(
        ssl_name2contents_[test::kSslServerPublicCertFile]);
  }

  // Returns full path to the model.
  std::string ModelPath(std::string_view model_dir,
                        std::string_view model_filename) const {
    const std::filesystem::path model_path = (
        std::filesystem::current_path() /
        model_dir / model_filename).make_preferred();
    return model_path.string();
  }

  // Mapping between the names of SSL credential files and the actual contents.
  absl::flat_hash_map<std::string, std::string> ssl_name2contents_;

  // Global configuration (this includes both client and the server).
  ClientConfig config_;

  // UNIX Domain Socket (UDS) path.
  std::string uds_path_;
};

// Check insecure credentials.
TEST_P(AuthEnd2EndTest, CheckInsecure) {
  InitConfig(&config_, /* use_uds= */GetParam());
  EXPECT_OK(BuildAndRun(config_));
}

// The certificate presented by the client is not checked by the server at all.
TEST_P(AuthEnd2EndTest, CheckSslNoClientVerification) {
  InitConfig(&config_, /* use_uds= */GetParam());

  // Prepare the server credentials and run insecure client.
  MakeServerSslConfig(config_.mutable_server(), /* verify_clients= */false);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Prepare the client credentials by setting the target name. Will use the
  // server public certificate authority from the server config.
  ClientAuthConfig *auth = config_.mutable_auth();
  auth->mutable_ssl()->set_target_name_override(test::kSslAltServerName);
  EXPECT_OK(BuildAndRun(config_));
}

// Mutual SSL/TLS verification: server requests client certificate and enforces
// that the client presents a certificate. This uses Certificate Authority (CA).
TEST_P(AuthEnd2EndTest, CheckSslWithClientVerification) {
  InitConfig(&config_, /* use_uds= */GetParam());

  // Prepare the server credentials and run insecure client.
  MakeServerSslConfig(config_.mutable_server(), /* verify_clients= */true);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Check that correctly setting target name override is not enough as client
  // does not present any credentials.
  ClientAuthConfig::SslConfig *client_ssl =
      config_.mutable_auth()->mutable_ssl();
  client_ssl->set_target_name_override(test::kSslAltServerName);
  EXPECT_FALSE(BuildAndRun(config_).ok());

  // Set up all the required certificates and keys. The server certificate and
  // key are already set up. Check successful handshake and run.
  ServerAuthConfig *server_auth = config_.mutable_server()->mutable_auth();
  server_auth->mutable_ssl()->set_custom_ca_cert(
      ssl_name2contents_[test::kSslClientCentralAuthCertFile]);
  client_ssl->set_client_cert(
      ssl_name2contents_[test::kSslClientPublicCertFile]);
  client_ssl->set_client_key(
      ssl_name2contents_[test::kSslClientPrivateKeyFile]);
  EXPECT_OK(BuildAndRun(config_));
}

INSTANTIATE_TEST_SUITE_P(
    AuthEnd2EndTestSuite, AuthEnd2EndTest,
    // Use UNIX Domain Sockets (UDS) or the default TCP sockets.
#if !defined(_MSC_VER)
    ::testing::Values(/* use_uds= */false, /* use_uds= */true));
#elif defined(_WIN32) || defined(_WIN64)
    // UNIX domain sockets are not supported in older versions of Windows.
    // See: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
    ::testing::Values(/* use_uds= */false));
#endif  // _MSC_VER (Windows).

}  // namespace
}  // namespace grpc
}  // namespace mozolm
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbStandardShader.h"
#include "otbFragmentShaderRegistry.h"
#include <GL/glew.h>

namespace otb
{

StandardShader::StandardShader()
  : m_MinRed(0),
    m_MaxRed(255),
    m_MinGreen(0),
    m_MaxGreen(255),
    m_MinBlue(0),
    m_MaxBlue(255),
    m_UseNoData(true),
    m_NoData(0),
    m_Gamma(1.),
    m_Alpha(1.),
    m_CurrentRed(0),
    m_CurrentGreen(0),
    m_CurrentBlue(0),
    m_LocalContrastRange(50),
    m_SpectralAngleRange(10),
    m_Center(),
    m_Radius(200),
    m_ChessboardSize(256),
    m_SliderPosition(500),
    m_VerticalSlider(false),
    m_ShaderType(SHADER_STANDARD)
{
  this->BuildShader();
}

StandardShader::~StandardShader()
{}

std::string StandardShader::GetSource() const
{
  return "#version 130 \n"                                              \
    "uniform sampler2D src;\n"                                          \
    "uniform vec4 shader_a;\n"                                          \
    "uniform vec4 shader_b;\n"                                          \
    "uniform int shader_use_no_data;\n"                                 \
    "uniform float shader_no_data;\n"                                   \
    "uniform vec3 shader_current;\n"                                    \
    "uniform vec4 shader_gamma;\n"                                      \
    "uniform float shader_alpha;\n"                                     \
    "uniform vec2 shader_center;\n"                                     \
    "uniform int shader_type;\n"                                        \
    "uniform float shader_radius;\n"                                    \
    "uniform float shader_localc_range;\n"                              \
    "uniform float shader_spectral_angle_range;\n"                      \
    "uniform float shader_chessboard_size;\n"                           \
    "uniform float shader_slider_pos;\n"                                \
    "uniform int shader_vertical_slider_flag;\n"                        \
    "void main (void) {\n"                                              \
    "vec4 p = texture2D(src, gl_TexCoord[0].xy);\n"                     \
    "gl_FragColor = clamp(pow((p+shader_b)*shader_a,shader_gamma), 0.0, 1.0);\n" \
    "gl_FragColor[3] = clamp(shader_alpha,0.0,1.0);\n"                  \
    "if(shader_use_no_data > 0 && vec3(p) == vec3(shader_no_data)){\n"  \
    "gl_FragColor[3] = 0.;\n"                                           \
    "}\n"                                                               \
    "float alpha = gl_FragColor[3];\n"                                  \
    "float dist = distance(gl_FragCoord.xy,shader_center);\n" \
    "if(shader_type == 1)\n"                                            \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "vec3 tmp = clamp((vec3(p)-vec3(shader_current)+vec3(shader_localc_range))/(2.*vec3(shader_localc_range)),0.0,1.0);\n" \
    "gl_FragColor[0] = tmp[0];\n"                                       \
    "gl_FragColor[1] = tmp[1];\n"                                       \
    "gl_FragColor[2] = tmp[2];\n"                                       \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "else if(shader_type == 2)"                                         \
    "{\n"                                                               \
    "gl_FragColor[3] = dist > shader_radius ? 1.0 : 0.0; \n"            \
    "}\n"                                                               \
    "else if(shader_type == 3)\n"                                       \
    "{\n"                                                               \
    "float alpha = (mod(floor(gl_FragCoord.x / shader_chessboard_size), 2.0) == 0.) != (mod(floor(gl_FragCoord.y / shader_chessboard_size), 2.0) == 1.) ? shader_alpha : 0.0;\n" \
    "gl_FragColor[3] = clamp(alpha,0.0,1.0);\n"                         \
    "}\n"                                                               \
    "else if(shader_type == 4)\n"                                       \
    "{\n"                                                               \
    "float alpha = (shader_vertical_slider_flag == 0 && gl_FragCoord.x > shader_slider_pos) || (shader_vertical_slider_flag == 1 && gl_FragCoord.y > shader_slider_pos) ? 1.0 : 0.0;\n" \
    "gl_FragColor[3] = clamp(alpha,0.0,1.0);\n"                         \
    "}\n"                                                               \
    "else if(shader_type == 5)\n"                                       \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "float angle = acos(clamp(dot(vec3(p),shader_current)/(length(vec3(p))*length(shader_current)),-1.0,1.0));\n" \
    "vec3 tmp = clamp(vec3(1.-shader_spectral_angle_range*abs(angle)/3.142),0.0,1.0);\n" \
    "gl_FragColor[0] = tmp[0];\n"                                       \
    "gl_FragColor[1] = tmp[1];\n"                                       \
    "gl_FragColor[2] = tmp[2];\n"                                       \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "else if(shader_type == 6)\n"                                       \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "vec2 size = vec2(textureSize(src,0));\n"                           \
    "vec2 dx = vec2(gl_TexCoord[0].xy);\n"                              \
    "dx[0]+=1.0/size[0];\n"                                             \
    "vec2 dy = vec2(gl_TexCoord[0].xy);\n"                              \
    "dy[1]+=1.0/size[1];\n"                                             \
    "vec4 pdx = texture2D(src, dx);\n"                                  \
    "vec4 pdy = texture2D(src, dy);\n"                                  \
    "gl_FragColor = clamp(pow(shader_a*(0.5*abs((pdx-p))+ 0.5*abs((pdy-p))),shader_gamma),0.0,1.0);\n" \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "}"
;}

std::string StandardShader::GetName() const
{
  return "StandardShader";
}

void StandardShader::SetupShader()
{
// Compute shifts and scales
  double shr,shg,shb,scr,scg,scb;
  shr = -m_MinRed;
  shg = -m_MinGreen;
  shb = -m_MinBlue;
  scr = 1./(m_MaxRed-m_MinRed);
  scg = 1./(m_MaxGreen-m_MinGreen);
  scb = 1./(m_MaxBlue-m_MinBlue);

  GLint shader_a = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_a");
  glUniform4f(shader_a,scr,scg,scb,1.);

  GLint shader_b = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_b");
  glUniform4f(shader_b,shr,shg,shb,0);

  GLint shader_use_no_data = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_use_no_data");
  glUniform1i(shader_use_no_data,m_UseNoData);

  GLint shader_no_data = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_no_data");
  glUniform1f(shader_no_data,m_NoData);

  GLint shader_gamma = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_gamma");
  glUniform4f(shader_gamma,m_Gamma,m_Gamma,m_Gamma,m_Gamma);

  GLint shader_alpha = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_alpha");
  glUniform1f(shader_alpha,m_Alpha);

  GLint shader_radius = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_radius");
  glUniform1f(shader_radius,m_Radius);

  GLint shader_center = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_center");
  glUniform2f(shader_center,m_Center[0],m_Center[1]);

  GLint shader_type = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_type");
  glUniform1i(shader_type,m_ShaderType);

  GLint shader_current = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_current");
  glUniform3f(shader_current,m_CurrentRed,m_CurrentGreen,m_CurrentBlue);

  GLint shader_localc_range = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_localc_range");
  glUniform1f(shader_localc_range,m_LocalContrastRange);

  GLint shader_spectral_angle_range = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_spectral_angle_range");
  glUniform1f(shader_spectral_angle_range,m_SpectralAngleRange);

  GLint shader_chessboard_size = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_chessboard_size");
  glUniform1f(shader_chessboard_size,m_ChessboardSize);

  GLint shader_slider_pos = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_slider_pos");
  glUniform1f(shader_slider_pos,m_SliderPosition);

  GLint shader_vertical_slider_flag = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_vertical_slider_flag");
  glUniform1i(shader_vertical_slider_flag,m_VerticalSlider);

}

} // End namespace otb

<commit_msg>ENH: Adding a small factor to gradient for better visualisation<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbStandardShader.h"
#include "otbFragmentShaderRegistry.h"
#include <GL/glew.h>

namespace otb
{

StandardShader::StandardShader()
  : m_MinRed(0),
    m_MaxRed(255),
    m_MinGreen(0),
    m_MaxGreen(255),
    m_MinBlue(0),
    m_MaxBlue(255),
    m_UseNoData(true),
    m_NoData(0),
    m_Gamma(1.),
    m_Alpha(1.),
    m_CurrentRed(0),
    m_CurrentGreen(0),
    m_CurrentBlue(0),
    m_LocalContrastRange(50),
    m_SpectralAngleRange(10),
    m_Center(),
    m_Radius(200),
    m_ChessboardSize(256),
    m_SliderPosition(500),
    m_VerticalSlider(false),
    m_ShaderType(SHADER_STANDARD)
{
  this->BuildShader();
}

StandardShader::~StandardShader()
{}

std::string StandardShader::GetSource() const
{
  return "#version 130 \n"                                              \
    "uniform sampler2D src;\n"                                          \
    "uniform vec4 shader_a;\n"                                          \
    "uniform vec4 shader_b;\n"                                          \
    "uniform int shader_use_no_data;\n"                                 \
    "uniform float shader_no_data;\n"                                   \
    "uniform vec3 shader_current;\n"                                    \
    "uniform vec4 shader_gamma;\n"                                      \
    "uniform float shader_alpha;\n"                                     \
    "uniform vec2 shader_center;\n"                                     \
    "uniform int shader_type;\n"                                        \
    "uniform float shader_radius;\n"                                    \
    "uniform float shader_localc_range;\n"                              \
    "uniform float shader_spectral_angle_range;\n"                      \
    "uniform float shader_chessboard_size;\n"                           \
    "uniform float shader_slider_pos;\n"                                \
    "uniform int shader_vertical_slider_flag;\n"                        \
    "void main (void) {\n"                                              \
    "vec4 p = texture2D(src, gl_TexCoord[0].xy);\n"                     \
    "gl_FragColor = clamp(pow((p+shader_b)*shader_a,shader_gamma), 0.0, 1.0);\n" \
    "gl_FragColor[3] = clamp(shader_alpha,0.0,1.0);\n"                  \
    "if(shader_use_no_data > 0 && vec3(p) == vec3(shader_no_data)){\n"  \
    "gl_FragColor[3] = 0.;\n"                                           \
    "}\n"                                                               \
    "float alpha = gl_FragColor[3];\n"                                  \
    "float dist = distance(gl_FragCoord.xy,shader_center);\n" \
    "if(shader_type == 1)\n"                                            \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "vec3 tmp = clamp((vec3(p)-vec3(shader_current)+vec3(shader_localc_range))/(2.*vec3(shader_localc_range)),0.0,1.0);\n" \
    "gl_FragColor[0] = tmp[0];\n"                                       \
    "gl_FragColor[1] = tmp[1];\n"                                       \
    "gl_FragColor[2] = tmp[2];\n"                                       \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "else if(shader_type == 2)"                                         \
    "{\n"                                                               \
    "gl_FragColor[3] = dist > shader_radius ? 1.0 : 0.0; \n"            \
    "}\n"                                                               \
    "else if(shader_type == 3)\n"                                       \
    "{\n"                                                               \
    "float alpha = (mod(floor(gl_FragCoord.x / shader_chessboard_size), 2.0) == 0.) != (mod(floor(gl_FragCoord.y / shader_chessboard_size), 2.0) == 1.) ? shader_alpha : 0.0;\n" \
    "gl_FragColor[3] = clamp(alpha,0.0,1.0);\n"                         \
    "}\n"                                                               \
    "else if(shader_type == 4)\n"                                       \
    "{\n"                                                               \
    "float alpha = (shader_vertical_slider_flag == 0 && gl_FragCoord.x > shader_slider_pos) || (shader_vertical_slider_flag == 1 && gl_FragCoord.y > shader_slider_pos) ? 1.0 : 0.0;\n" \
    "gl_FragColor[3] = clamp(alpha,0.0,1.0);\n"                         \
    "}\n"                                                               \
    "else if(shader_type == 5)\n"                                       \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "float angle = acos(clamp(dot(vec3(p),shader_current)/(length(vec3(p))*length(shader_current)),-1.0,1.0));\n" \
    "vec3 tmp = clamp(vec3(1.-shader_spectral_angle_range*abs(angle)/3.142),0.0,1.0);\n" \
    "gl_FragColor[0] = tmp[0];\n"                                       \
    "gl_FragColor[1] = tmp[1];\n"                                       \
    "gl_FragColor[2] = tmp[2];\n"                                       \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "else if(shader_type == 6)\n"                                       \
    "{\n"                                                               \
    "if(dist < shader_radius)\n"                                        \
    "{\n"                                                               \
    "vec2 size = vec2(textureSize(src,0));\n"                           \
    "vec2 dx = vec2(gl_TexCoord[0].xy);\n"                              \
    "dx[0]+=1.0/size[0];\n"                                             \
    "vec2 dy = vec2(gl_TexCoord[0].xy);\n"                              \
    "dy[1]+=1.0/size[1];\n"                                             \
    "vec4 pdx = texture2D(src, dx);\n"                                  \
    "vec4 pdy = texture2D(src, dy);\n"                                  \
    "gl_FragColor = clamp(pow(5*shader_a*(0.5*abs((pdx-p))+ 0.5*abs((pdy-p))),shader_gamma),0.0,1.0);\n" \
    "gl_FragColor[3] = alpha;\n"                                        \
    "}\n"                                                               \
    "}\n"                                                               \
    "}"
;}

std::string StandardShader::GetName() const
{
  return "StandardShader";
}

void StandardShader::SetupShader()
{
// Compute shifts and scales
  double shr,shg,shb,scr,scg,scb;
  shr = -m_MinRed;
  shg = -m_MinGreen;
  shb = -m_MinBlue;
  scr = 1./(m_MaxRed-m_MinRed);
  scg = 1./(m_MaxGreen-m_MinGreen);
  scb = 1./(m_MaxBlue-m_MinBlue);

  GLint shader_a = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_a");
  glUniform4f(shader_a,scr,scg,scb,1.);

  GLint shader_b = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_b");
  glUniform4f(shader_b,shr,shg,shb,0);

  GLint shader_use_no_data = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_use_no_data");
  glUniform1i(shader_use_no_data,m_UseNoData);

  GLint shader_no_data = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_no_data");
  glUniform1f(shader_no_data,m_NoData);

  GLint shader_gamma = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_gamma");
  glUniform4f(shader_gamma,m_Gamma,m_Gamma,m_Gamma,m_Gamma);

  GLint shader_alpha = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_alpha");
  glUniform1f(shader_alpha,m_Alpha);

  GLint shader_radius = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_radius");
  glUniform1f(shader_radius,m_Radius);

  GLint shader_center = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_center");
  glUniform2f(shader_center,m_Center[0],m_Center[1]);

  GLint shader_type = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_type");
  glUniform1i(shader_type,m_ShaderType);

  GLint shader_current = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_current");
  glUniform3f(shader_current,m_CurrentRed,m_CurrentGreen,m_CurrentBlue);

  GLint shader_localc_range = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_localc_range");
  glUniform1f(shader_localc_range,m_LocalContrastRange);

  GLint shader_spectral_angle_range = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_spectral_angle_range");
  glUniform1f(shader_spectral_angle_range,m_SpectralAngleRange);

  GLint shader_chessboard_size = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_chessboard_size");
  glUniform1f(shader_chessboard_size,m_ChessboardSize);

  GLint shader_slider_pos = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_slider_pos");
  glUniform1f(shader_slider_pos,m_SliderPosition);

  GLint shader_vertical_slider_flag = glGetUniformLocation(otb::FragmentShaderRegistry::Instance()->GetShaderProgram("StandardShader"), "shader_vertical_slider_flag");
  glUniform1i(shader_vertical_slider_flag,m_VerticalSlider);

}

} // End namespace otb

<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   MechanicAngularVelocityTransformer.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-08-05
//!
//! @brief Contains an angular velocity transformer component
//!
//$Id$

#ifndef MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED
#define MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicAngularVelocityTransformer : public ComponentQ
    {

    private:
        double *mpW;
        double *mpND_t, *mpND_a, *mpND_w, *mpND_c, *mpND_Zx;
        Integrator mInt;
        Port *mpIn, *mpOut;

    public:
        static Component *Creator()
        {
            return new MechanicAngularVelocityTransformer();
        }

        void configure()
        {
            mpIn = addReadPort("in", "NodeSignal", Port::NotRequired);
            mpOut = addPowerPort("out", "NodeMechanicRotational");
            addInputVariable("omega", "Generated angular velocity", "[rad/s]", 0.0, &mpW);
        }

        void initialize()
        {
            mpND_t = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::Torque);
            mpND_a = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::Angle);
            mpND_w = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::AngularVelocity);
            mpND_c = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::WaveVariable);
            mpND_Zx = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::CharImpedance);

            mInt.initialize(mTimestep, (*mpW), 0.0);
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            double w, c, Zx, a, t;
            w = (*mpW);
            c = (*mpND_c);
            Zx = (*mpND_Zx);

            //Spring equations
            a = mInt.update(w);
            t = c + Zx*w;

            //Write values to nodes
            (*mpND_t) = t;
            (*mpND_a) = a;
            (*mpND_w) = w;
        }
    };
}

#endif // MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED

<commit_msg>Removed useless inport<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//!
//! @file   MechanicAngularVelocityTransformer.hpp
//! @author Robert Braun <robert.braun@liu.se>
//! @date   2010-08-05
//!
//! @brief Contains an angular velocity transformer component
//!
//$Id$

#ifndef MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED
#define MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicAngularVelocityTransformer : public ComponentQ
    {

    private:
        Integrator mInt;
        Port *mpOut;
        double *mpOut_t, *mpOut_a, *mpOut_w, *mpOut_c, *mpOut_Zx;
        double *mpW;

    public:
        static Component *Creator()
        {
            return new MechanicAngularVelocityTransformer();
        }

        void configure()
        {
            mpOut = addPowerPort("out", "NodeMechanicRotational");
            addInputVariable("omega", "Generated angular velocity", "[rad/s]", 0.0, &mpW);
        }

        void initialize()
        {
            mpOut_t = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::Torque);
            mpOut_a = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::Angle);
            mpOut_w = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::AngularVelocity);
            mpOut_c = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::WaveVariable);
            mpOut_Zx = getSafeNodeDataPtr(mpOut, NodeMechanicRotational::CharImpedance);

            mInt.initialize(mTimestep, (*mpW), (*mpOut_a));
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            double a, t;
            const double w = (*mpW);
            const double c = (*mpOut_c);
            const double Zx = (*mpOut_Zx);

            //Spring equations
            a = mInt.update(w);
            t = c + Zx*w;

            //Write values to nodes
            (*mpOut_t) = t;
            (*mpOut_a) = a;
            (*mpOut_w) = w;
        }
    };
}

#endif // MECHANICANGULARVELOCITYTRANSFORMER_HPP_INCLUDED

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPyramidImageRegistrationMethod.h"

#include "mitkException.h"
#include "mitkImageAccessByItk.h"

mitk::PyramidImageRegistrationMethod::PyramidImageRegistrationMethod()
  : m_FixedImage(NULL),
    m_MovingImage(NULL),
    m_CrossModalityRegistration(true),
    m_UseAffineTransform(true),
    m_UseWindowedSincInterpolator(false),
    m_UseNearestNeighborInterpolator(false),
    m_UseMask(false),
    m_EstimatedParameters(NULL),
    m_InitialParameters(NULL),
    m_Verbose(false)
{

}

mitk::PyramidImageRegistrationMethod::~PyramidImageRegistrationMethod()
{
  if( m_EstimatedParameters != NULL)
  {
    delete [] m_EstimatedParameters;
  }

}

void mitk::PyramidImageRegistrationMethod::SetFixedImage(mitk::Image::Pointer fixed)
{
  if( fixed.IsNotNull() )
  {
    m_FixedImage = fixed;
  }
}

void mitk::PyramidImageRegistrationMethod::SetMovingImage(mitk::Image::Pointer moving)
{
  if( moving.IsNotNull() )
  {
    m_MovingImage = moving;
  }
}

void mitk::PyramidImageRegistrationMethod::SetFixedImageMask(mitk::Image::Pointer mask)
{
  m_FixedImageMask = mask;
}

void mitk::PyramidImageRegistrationMethod::Update()
{
  if( m_MovingImage.IsNull() )
  {
    mitkThrow() << " Moving image is null";
  }

  if( m_FixedImage.IsNull() )
  {
    mitkThrow() << " Moving image is null";
  }

  unsigned int allowedDimension = 3;

  if( m_FixedImage->GetDimension() != allowedDimension ||
      m_MovingImage->GetDimension() != allowedDimension )
  {
    mitkThrow() << " Only 3D Images supported.";
  }

  //
  // One possibility: use the FixedDimesnionByItk, but this instantiates ALL possible
  // pixel type combinations!
  // AccessTwoImagesFixedDimensionByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3);
  // in helper: TypeSubset : short, float
  AccessTwoImagesFixedDimensionTypeSubsetByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3);

}

mitk::PyramidImageRegistrationMethod::TransformMatrixType mitk::PyramidImageRegistrationMethod
::GetLastRotationMatrix()
{
  TransformMatrixType output;
  if( m_EstimatedParameters == NULL )
  {
    output.set_identity();
    return output;
  }

  typedef itk::MatrixOffsetTransformBase< double, 3, 3> BaseTransformType;
  BaseTransformType::Pointer base_transform = BaseTransformType::New();

  if( this->m_UseAffineTransform )
  {
    typedef itk::AffineTransform< double > TransformType;
    TransformType::Pointer transform = TransformType::New();

    TransformType::ParametersType affine_params( TransformType::ParametersDimension );
    this->GetParameters( &affine_params[0] );

    transform->SetParameters( affine_params );
    base_transform = transform;
  }
  else
  {
    typedef itk::Euler3DTransform< double > RigidTransformType;
    RigidTransformType::Pointer rtransform = RigidTransformType::New();

    RigidTransformType::ParametersType rigid_params( RigidTransformType::ParametersDimension  );
    this->GetParameters( &rigid_params[0] );

    rtransform->SetParameters( rigid_params );

    base_transform = rtransform;
  }

  return base_transform->GetMatrix().GetVnlMatrix();

}

mitk::Image::Pointer mitk::PyramidImageRegistrationMethod
::GetResampledMovingImage()
{

  mitk::Image::Pointer output = mitk::Image::New();
  //output->Initialize( this->m_FixedImage );

  AccessFixedDimensionByItk_1( this->m_MovingImage, ResampleMitkImage, 3, output );

  return output;

}

mitk::Image::Pointer mitk::PyramidImageRegistrationMethod::GetResampledMovingImage(mitk::Image::Pointer movingImage, double* transform)
{
  mitk::Image::Pointer output = mitk::Image::New();

  unsigned int dim = 12;
  if( !m_UseAffineTransform )
    dim = 6;

  if (m_EstimatedParameters == NULL)
    m_EstimatedParameters = new double[dim];

  double tmpParams[12];
  // save and set temporal transformation values
  for( unsigned int i=0; i<dim; i++)
  {
    tmpParams[i] = m_EstimatedParameters[i];
    m_EstimatedParameters[i] = transform[i];
  }

  AccessFixedDimensionByItk_1( movingImage, ResampleMitkImage, 3, output );

  // Restore old values
  for( unsigned int i=0; i<dim; i++)
  {
    m_EstimatedParameters[i] = tmpParams[i];
  }

  return output;

}
<commit_msg>Fixed variable initialization<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPyramidImageRegistrationMethod.h"

#include "mitkException.h"
#include "mitkImageAccessByItk.h"

mitk::PyramidImageRegistrationMethod::PyramidImageRegistrationMethod()
  : m_FixedImage(NULL),
    m_MovingImage(NULL),
    m_CrossModalityRegistration(true),
    m_UseAffineTransform(true),
    m_UseWindowedSincInterpolator(false),
    m_UseNearestNeighborInterpolator(false),
    m_UseMask(false),
    m_EstimatedParameters(0),
    m_InitialParameters(0),
    m_Verbose(false)
{

}

mitk::PyramidImageRegistrationMethod::~PyramidImageRegistrationMethod()
{
  if( m_EstimatedParameters != NULL)
  {
    delete [] m_EstimatedParameters;
  }

}

void mitk::PyramidImageRegistrationMethod::SetFixedImage(mitk::Image::Pointer fixed)
{
  if( fixed.IsNotNull() )
  {
    m_FixedImage = fixed;
  }
}

void mitk::PyramidImageRegistrationMethod::SetMovingImage(mitk::Image::Pointer moving)
{
  if( moving.IsNotNull() )
  {
    m_MovingImage = moving;
  }
}

void mitk::PyramidImageRegistrationMethod::SetFixedImageMask(mitk::Image::Pointer mask)
{
  m_FixedImageMask = mask;
}

void mitk::PyramidImageRegistrationMethod::Update()
{
  if( m_MovingImage.IsNull() )
  {
    mitkThrow() << " Moving image is null";
  }

  if( m_FixedImage.IsNull() )
  {
    mitkThrow() << " Moving image is null";
  }

  unsigned int allowedDimension = 3;

  if( m_FixedImage->GetDimension() != allowedDimension ||
      m_MovingImage->GetDimension() != allowedDimension )
  {
    mitkThrow() << " Only 3D Images supported.";
  }

  //
  // One possibility: use the FixedDimesnionByItk, but this instantiates ALL possible
  // pixel type combinations!
  // AccessTwoImagesFixedDimensionByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3);
  // in helper: TypeSubset : short, float
  AccessTwoImagesFixedDimensionTypeSubsetByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3);

}

mitk::PyramidImageRegistrationMethod::TransformMatrixType mitk::PyramidImageRegistrationMethod
::GetLastRotationMatrix()
{
  TransformMatrixType output;
  if( m_EstimatedParameters == NULL )
  {
    output.set_identity();
    return output;
  }

  typedef itk::MatrixOffsetTransformBase< double, 3, 3> BaseTransformType;
  BaseTransformType::Pointer base_transform = BaseTransformType::New();

  if( this->m_UseAffineTransform )
  {
    typedef itk::AffineTransform< double > TransformType;
    TransformType::Pointer transform = TransformType::New();

    TransformType::ParametersType affine_params( TransformType::ParametersDimension );
    this->GetParameters( &affine_params[0] );

    transform->SetParameters( affine_params );
    base_transform = transform;
  }
  else
  {
    typedef itk::Euler3DTransform< double > RigidTransformType;
    RigidTransformType::Pointer rtransform = RigidTransformType::New();

    RigidTransformType::ParametersType rigid_params( RigidTransformType::ParametersDimension  );
    this->GetParameters( &rigid_params[0] );

    rtransform->SetParameters( rigid_params );

    base_transform = rtransform;
  }

  return base_transform->GetMatrix().GetVnlMatrix();

}

mitk::Image::Pointer mitk::PyramidImageRegistrationMethod
::GetResampledMovingImage()
{

  mitk::Image::Pointer output = mitk::Image::New();
  //output->Initialize( this->m_FixedImage );

  AccessFixedDimensionByItk_1( this->m_MovingImage, ResampleMitkImage, 3, output );

  return output;

}

mitk::Image::Pointer mitk::PyramidImageRegistrationMethod::GetResampledMovingImage(mitk::Image::Pointer movingImage, double* transform)
{
  mitk::Image::Pointer output = mitk::Image::New();

  unsigned int dim = 12;
  if( !m_UseAffineTransform )
    dim = 6;

  if (m_EstimatedParameters == NULL)
    m_EstimatedParameters = new double[dim];

  double tmpParams[12];
  // save and set temporal transformation values
  for( unsigned int i=0; i<dim; i++)
  {
    tmpParams[i] = m_EstimatedParameters[i];
    m_EstimatedParameters[i] = transform[i];
  }

  AccessFixedDimensionByItk_1( movingImage, ResampleMitkImage, 3, output );

  // Restore old values
  for( unsigned int i=0; i<dim; i++)
  {
    m_EstimatedParameters[i] = tmpParams[i];
  }

  return output;

}
<|endoftext|>