<commit_before>/*
 * Implementation for the mbed library
 * https://github.com/mbedmicro/mbed
 *
 * Copyright (c) 2016 Christopher Haster
 *
 * 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.
 */
#include "equeue/equeue_platform.h"

#if defined(EQUEUE_PLATFORM_MBED)

#include <stdbool.h>
#include <string.h>
#include "cmsis.h"
#include "platform/mbed_critical.h"
#include "drivers/Timer.h"
#include "drivers/Ticker.h"
#include "drivers/Timeout.h"
#include "drivers/LowPowerTimeout.h"
#include "drivers/LowPowerTicker.h"
#include "drivers/LowPowerTimer.h"

using namespace mbed;

// Ticker operations
#if MBED_CONF_RTOS_API_PRESENT

#include "rtos/Kernel.h"

unsigned equeue_tick()
{
    return rtos::Kernel::get_ms_count();
}

#else

#if MBED_CONF_EVENTS_USE_LOWPOWER_TIMER_TICKER

#define ALIAS_TIMER      LowPowerTimer
#define ALIAS_TICKER     LowPowerTicker
#define ALIAS_TIMEOUT    LowPowerTimeout
#else
#define ALIAS_TIMER      Timer
#define ALIAS_TICKER     Ticker
#define ALIAS_TIMEOUT    Timeout
#endif

static bool equeue_tick_inited = false;
static volatile unsigned equeue_minutes = 0;
static unsigned equeue_timer[
     (sizeof(ALIAS_TIMER) + sizeof(unsigned) - 1) / sizeof(unsigned)];
static unsigned equeue_ticker[
     (sizeof(ALIAS_TICKER) + sizeof(unsigned) - 1) / sizeof(unsigned)];

static void equeue_tick_update()
{
    equeue_minutes += reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->read_ms();
    reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->reset();
}

static void equeue_tick_init()
{
    MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(ALIAS_TIMER),
                       "The equeue_timer buffer must fit the class Timer");
    MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(ALIAS_TICKER),
                       "The equeue_ticker buffer must fit the class Ticker");
    ALIAS_TIMER *timer = new (equeue_timer) ALIAS_TIMER;
    ALIAS_TICKER *ticker = new (equeue_ticker) ALIAS_TICKER;

    equeue_minutes = 0;
    timer->start();
    ticker->attach_us(equeue_tick_update, 1000 << 16);

    equeue_tick_inited = true;
}

unsigned equeue_tick()
{
    if (!equeue_tick_inited) {
        equeue_tick_init();
    }

    unsigned minutes;
    unsigned ms;

    do {
        minutes = equeue_minutes;
        ms = reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->read_ms();
    } while (minutes != equeue_minutes);

    return minutes + ms;
}

#endif

// Mutex operations
int equeue_mutex_create(equeue_mutex_t *m)
{
    return 0;
}
void equeue_mutex_destroy(equeue_mutex_t *m) { }

void equeue_mutex_lock(equeue_mutex_t *m)
{
    core_util_critical_section_enter();
}

void equeue_mutex_unlock(equeue_mutex_t *m)
{
    core_util_critical_section_exit();
}

// Semaphore operations
#ifdef MBED_CONF_RTOS_API_PRESENT

#include "rtos/EventFlags.h"

MBED_STATIC_ASSERT(sizeof(equeue_sema_t) == sizeof(rtos::EventFlags), "equeue_sema_t / rtos::EventFlags mismatch");

int equeue_sema_create(equeue_sema_t *s)
{
    new (s) rtos::EventFlags("equeue");
    return 0;
}

void equeue_sema_destroy(equeue_sema_t *s)
{
    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    ef->~EventFlags();
}

void equeue_sema_signal(equeue_sema_t *s)
{
    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    ef->set(1);
}

bool equeue_sema_wait(equeue_sema_t *s, int ms)
{
    if (ms < 0) {
        ms = osWaitForever;
    }

    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    return ef->wait_any(1, ms) == 1;
}

#else

// Semaphore operations
int equeue_sema_create(equeue_sema_t *s)
{
    *s = 0;
    return 0;
}

void equeue_sema_destroy(equeue_sema_t *s)
{
}

void equeue_sema_signal(equeue_sema_t *s)
{
    *s = 1;
}

static void equeue_sema_timeout(equeue_sema_t *s)
{
    *s = -1;
}

bool equeue_sema_wait(equeue_sema_t *s, int ms)
{
    ALIAS_TIMEOUT timeout;
    if (ms > 0) {
        timeout.attach_us(callback(equeue_sema_timeout, s), (us_timestamp_t)ms * 1000);
    }

    core_util_critical_section_enter();
    while (!*s && ms != 0) {
        sleep();
        core_util_critical_section_exit();
        __ISB();
        core_util_critical_section_enter();
    }

    int signal = *s;
    *s = 0;
    core_util_critical_section_exit();

    return (signal > 0);
}

#endif

#endif
<commit_msg>equeue - avoid Kernel::get_ms_count from IRQ<commit_after>/*
 * Implementation for the mbed library
 * https://github.com/mbedmicro/mbed
 *
 * Copyright (c) 2016 Christopher Haster
 *
 * 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.
 */
#include "equeue/equeue_platform.h"

#if defined(EQUEUE_PLATFORM_MBED)

#include <stdbool.h>
#include <string.h>
#include "cmsis.h"
#include "platform/mbed_critical.h"
#include "drivers/Timer.h"
#include "drivers/Ticker.h"
#include "drivers/Timeout.h"
#include "drivers/LowPowerTimeout.h"
#include "drivers/LowPowerTicker.h"
#include "drivers/LowPowerTimer.h"

using namespace mbed;

// Ticker operations
#if MBED_CONF_RTOS_API_PRESENT

#include "rtos/Kernel.h"
#include "platform/mbed_os_timer.h"

unsigned equeue_tick()
{
    // It is not safe to call get_ms_count from ISRs, both
    // because documentation says so, and because it will give
    // a stale value from the RTOS if the interrupt has woken
    // us out of sleep - the RTOS will not have updated its
    // ticks yet.
    if (core_util_is_isr_active()) {
        // And the documentation further says that this
        // should not be called from critical sections, for
        // performance reasons, but I don't have a good
        // current alternative!
        return mbed::internal::os_timer->get_time() / 1000;
    } else {
        return rtos::Kernel::get_ms_count();
    }
}

#else

#if MBED_CONF_EVENTS_USE_LOWPOWER_TIMER_TICKER

#define ALIAS_TIMER      LowPowerTimer
#define ALIAS_TICKER     LowPowerTicker
#define ALIAS_TIMEOUT    LowPowerTimeout
#else
#define ALIAS_TIMER      Timer
#define ALIAS_TICKER     Ticker
#define ALIAS_TIMEOUT    Timeout
#endif

static bool equeue_tick_inited = false;
static volatile unsigned equeue_minutes = 0;
static unsigned equeue_timer[
     (sizeof(ALIAS_TIMER) + sizeof(unsigned) - 1) / sizeof(unsigned)];
static unsigned equeue_ticker[
     (sizeof(ALIAS_TICKER) + sizeof(unsigned) - 1) / sizeof(unsigned)];

static void equeue_tick_update()
{
    equeue_minutes += reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->read_ms();
    reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->reset();
}

static void equeue_tick_init()
{
    MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(ALIAS_TIMER),
                       "The equeue_timer buffer must fit the class Timer");
    MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(ALIAS_TICKER),
                       "The equeue_ticker buffer must fit the class Ticker");
    ALIAS_TIMER *timer = new (equeue_timer) ALIAS_TIMER;
    ALIAS_TICKER *ticker = new (equeue_ticker) ALIAS_TICKER;

    equeue_minutes = 0;
    timer->start();
    ticker->attach_us(equeue_tick_update, 1000 << 16);

    equeue_tick_inited = true;
}

unsigned equeue_tick()
{
    if (!equeue_tick_inited) {
        equeue_tick_init();
    }

    unsigned minutes;
    unsigned ms;

    do {
        minutes = equeue_minutes;
        ms = reinterpret_cast<ALIAS_TIMER *>(equeue_timer)->read_ms();
    } while (minutes != equeue_minutes);

    return minutes + ms;
}

#endif

// Mutex operations
int equeue_mutex_create(equeue_mutex_t *m)
{
    return 0;
}
void equeue_mutex_destroy(equeue_mutex_t *m) { }

void equeue_mutex_lock(equeue_mutex_t *m)
{
    core_util_critical_section_enter();
}

void equeue_mutex_unlock(equeue_mutex_t *m)
{
    core_util_critical_section_exit();
}

// Semaphore operations
#ifdef MBED_CONF_RTOS_API_PRESENT

#include "rtos/EventFlags.h"

MBED_STATIC_ASSERT(sizeof(equeue_sema_t) == sizeof(rtos::EventFlags), "equeue_sema_t / rtos::EventFlags mismatch");

int equeue_sema_create(equeue_sema_t *s)
{
    new (s) rtos::EventFlags("equeue");
    return 0;
}

void equeue_sema_destroy(equeue_sema_t *s)
{
    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    ef->~EventFlags();
}

void equeue_sema_signal(equeue_sema_t *s)
{
    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    ef->set(1);
}

bool equeue_sema_wait(equeue_sema_t *s, int ms)
{
    if (ms < 0) {
        ms = osWaitForever;
    }

    rtos::EventFlags *ef = reinterpret_cast<rtos::EventFlags *>(s);
    return ef->wait_any(1, ms) == 1;
}

#else

// Semaphore operations
int equeue_sema_create(equeue_sema_t *s)
{
    *s = 0;
    return 0;
}

void equeue_sema_destroy(equeue_sema_t *s)
{
}

void equeue_sema_signal(equeue_sema_t *s)
{
    *s = 1;
}

static void equeue_sema_timeout(equeue_sema_t *s)
{
    *s = -1;
}

bool equeue_sema_wait(equeue_sema_t *s, int ms)
{
    ALIAS_TIMEOUT timeout;
    if (ms > 0) {
        timeout.attach_us(callback(equeue_sema_timeout, s), (us_timestamp_t)ms * 1000);
    }

    core_util_critical_section_enter();
    while (!*s && ms != 0) {
        sleep();
        core_util_critical_section_exit();
        __ISB();
        core_util_critical_section_enter();
    }

    int signal = *s;
    *s = 0;
    core_util_critical_section_exit();

    return (signal > 0);
}

#endif

#endif
<|endoftext|>


<commit_before>#include "MenuState.h"
#include "GameStateHandler.h"

MenuState::MenuState()
{
}

MenuState::~MenuState()
{
}

int MenuState::ShutDown()
{
	int result = 1;
	return result;
}

int MenuState::Initialize(GameStateHandler * gsh, ComponentHandler* cHandler, Camera* cameraRef)
{
	int result = 0;

	result = GameState::InitializeBase(gsh, cHandler, cameraRef);

	this->m_cHandlerPtr = cHandler;
	this->m_cameraRef = cameraRef;

	this->m_lockTarget = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	DirectX::XMVECTOR targetOffset = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	float distance = 4.0f;
	this->m_cameraRef->SetCameraPivot(&this->m_lockTarget, targetOffset, distance);

	for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
	{
		this->m_menuButtons[i].m_uiComp = cHandler->GetUIComponent();
		this->m_menuButtons[i].m_uiComp->active = 1;
		this->m_menuButtons[i].m_uiComp->position = DirectX::XMFLOAT2(100.f, 200.f + (i * 150.f));
		this->m_menuButtons[i].m_uiComp->size = DirectX::XMFLOAT2(400.f, 100.f);
		this->m_menuButtons[i].m_textComp = cHandler->GetTextComponent();
		this->m_menuButtons[i].m_textComp->active = 1;
		this->m_menuButtons[i].m_textComp->position = DirectX::XMFLOAT2(125.f, 220.f + (i * 150.f));
	}
	for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
	{
		int newI = i - m_NR_OF_MAIN_MENU_ITEMS;
		this->m_menuButtons[i].m_uiComp = cHandler->GetUIComponent();
		this->m_menuButtons[i].m_uiComp->active = 0;
		this->m_menuButtons[i].m_uiComp->position = DirectX::XMFLOAT2(100.f, 200.f + (newI * 150.f));
		this->m_menuButtons[i].m_uiComp->size = DirectX::XMFLOAT2(400.f, 100.f);
		this->m_menuButtons[i].m_textComp = cHandler->GetTextComponent();
		this->m_menuButtons[i].m_textComp->active = 0;
		this->m_menuButtons[i].m_textComp->position = DirectX::XMFLOAT2(125.f, 220.f + (newI * 150.f));
	}

	this->m_menuButtons[0].m_textComp->text = L"Start Game";
	this->m_menuButtons[2].m_textComp->text = L"Quit Game";
	this->m_menuButtons[1].m_textComp->text = L"Options";

	this->m_menuButtons[3].m_textComp->text = L"Toggle Fullscreen";
	this->m_menuButtons[4].m_textComp->text = L"Go Back";

	this->markedItem = 0;
	this->m_menuButtons[this->markedItem].SetHovered(true);

	return result;
}

int MenuState::Update(float dt, InputHandler * inputHandler)
{
	int result = 1;

	DirectX::XMFLOAT2 mousePos = inputHandler->GetMousePos();

	switch (this->menuState)
	{
	case 0: //Main menu
		for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
		{
			this->m_menuButtons[i].m_uiComp->UpdateHover(mousePos);
			if (this->m_menuButtons[i].m_uiComp->isHovered)
			{
				this->m_menuButtons[i].SetHovered(true);
				this->markedItem = i;
			}
			else if (i != this->markedItem)
			{
				this->m_menuButtons[i].SetHovered(false);
			}
		}

		if (inputHandler->IsMouseKeyReleased(SDL_BUTTON_LEFT))
		{
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].m_uiComp->UpdateClicked(mousePos);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_RETURN))
		{
			this->m_menuButtons[markedItem].m_uiComp->wasClicked = true;
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_DOWN))
		{
			if (this->markedItem < this->m_NR_OF_MAIN_MENU_ITEMS - 1)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem++;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_UP))
		{
			if (this->markedItem > 0)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem--;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}

		if (this->m_menuButtons[0].m_uiComp->CheckClicked())
		{
			//Start game was clicked

			//Create, Initialize and push a LevelSelectState
			LevelSelectState* levelSelect = new LevelSelectState();
			result = levelSelect->Initialize(this->m_gsh, this->m_cHandlerPtr, this->m_cameraRef);

			//If the initialization was successful
			if (result > 0)
			{
				//Push it to the gamestate stack/vector
				this->m_gsh->PushStateToStack(levelSelect);

				levelSelect->LoadLevel(std::string("../ResourceLib/AssetFiles/TestingLevel.level"));
			}
			else
			{
				//Delete it
				delete levelSelect;
				levelSelect = nullptr;
			}

			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
		}
		else if (this->m_menuButtons[1].m_uiComp->CheckClicked())
		{
			//Options was clicked
			this->m_menuButtons[this->markedItem].SetHovered(false);
			this->markedItem = this->m_NR_OF_MAIN_MENU_ITEMS;
			this->m_menuButtons[this->markedItem].SetHovered(true);
			this->menuState = 1;
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(true);
			}
		}
		else if (this->m_menuButtons[2].m_uiComp->CheckClicked())
		{
			//Quit game was clicked
			result = 0;
		}
		break;

	case 1: //Options Menu
		for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_OPTIONS_MENU_ITEMS; i++)
		{
			this->m_menuButtons[i].m_uiComp->UpdateHover(mousePos);
			if (this->m_menuButtons[i].m_uiComp->isHovered)
			{
				this->m_menuButtons[i].SetHovered(true);
				this->markedItem = i;
			}
			else if (i != this->markedItem)
			{
				this->m_menuButtons[i].SetHovered(false);
			}
		}

		if (inputHandler->IsMouseKeyReleased(SDL_BUTTON_LEFT))
		{
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_OPTIONS_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].m_uiComp->UpdateClicked(mousePos);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_RETURN))
		{
			this->m_menuButtons[markedItem].m_uiComp->wasClicked = true;
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_DOWN))
		{
			if (this->markedItem < this->m_NR_OF_MENU_ITEMS - 1)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem++;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_UP))
		{
			if (this->markedItem > this->m_NR_OF_MAIN_MENU_ITEMS)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem--;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}

		if (this->m_menuButtons[3].m_uiComp->CheckClicked())
		{
			//Toggle fullscreen was clicked
			//Cheating by telling the system the user pressed F
			inputHandler->SetKeyState(SDL_SCANCODE_F, true); //Seems this does not reset, ever
		}
		else if (this->m_menuButtons[4].m_uiComp->CheckClicked())
		{
			//Return to main menu was clicked
			inputHandler->SetKeyState(SDL_SCANCODE_F, false); //Temporary cheat
			this->m_menuButtons[this->markedItem].SetHovered(false);
			this->markedItem = 0;
			this->m_menuButtons[this->markedItem].SetHovered(true);
			this->menuState = 0;
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(true);
			}
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
		}

		break;
	default:
		break;
	}

	return result;
}
<commit_msg>FIX changed some variable fetching to const values<commit_after>#include "MenuState.h"
#include "GameStateHandler.h"

MenuState::MenuState()
{
}

MenuState::~MenuState()
{
}

int MenuState::ShutDown()
{
	int result = 1;
	return result;
}

int MenuState::Initialize(GameStateHandler * gsh, ComponentHandler* cHandler, Camera* cameraRef)
{
	int result = 0;

	result = GameState::InitializeBase(gsh, cHandler, cameraRef);

	this->m_cHandlerPtr = cHandler;
	this->m_cameraRef = cameraRef;

	this->m_lockTarget = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	DirectX::XMVECTOR targetOffset = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	float distance = 4.0f;
	this->m_cameraRef->SetCameraPivot(&this->m_lockTarget, targetOffset, distance);

	for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
	{
		this->m_menuButtons[i].m_uiComp = cHandler->GetUIComponent();
		this->m_menuButtons[i].m_uiComp->active = 1;
		this->m_menuButtons[i].m_uiComp->position = DirectX::XMFLOAT2(100.f, 200.f + (i * 150.f));
		this->m_menuButtons[i].m_uiComp->size = DirectX::XMFLOAT2(400.f, 100.f);
		this->m_menuButtons[i].m_textComp = cHandler->GetTextComponent();
		this->m_menuButtons[i].m_textComp->active = 1;
		this->m_menuButtons[i].m_textComp->position = DirectX::XMFLOAT2(125.f, 220.f + (i * 150.f));
	}
	for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
	{
		int newI = i - m_NR_OF_MAIN_MENU_ITEMS;
		this->m_menuButtons[i].m_uiComp = cHandler->GetUIComponent();
		this->m_menuButtons[i].m_uiComp->active = 0;
		this->m_menuButtons[i].m_uiComp->position = DirectX::XMFLOAT2(100.f, 200.f + (newI * 150.f));
		this->m_menuButtons[i].m_uiComp->size = DirectX::XMFLOAT2(400.f, 100.f);
		this->m_menuButtons[i].m_textComp = cHandler->GetTextComponent();
		this->m_menuButtons[i].m_textComp->active = 0;
		this->m_menuButtons[i].m_textComp->position = DirectX::XMFLOAT2(125.f, 220.f + (newI * 150.f));
	}

	this->m_menuButtons[0].m_textComp->text = L"Start Game";
	this->m_menuButtons[2].m_textComp->text = L"Quit Game";
	this->m_menuButtons[1].m_textComp->text = L"Options";

	this->m_menuButtons[3].m_textComp->text = L"Toggle Fullscreen";
	this->m_menuButtons[4].m_textComp->text = L"Go Back";

	this->markedItem = 0;
	this->m_menuButtons[0].SetHovered(true);

	return result;
}

int MenuState::Update(float dt, InputHandler * inputHandler)
{
	int result = 1;

	DirectX::XMFLOAT2 mousePos = inputHandler->GetMousePos();

	switch (this->menuState)
	{
	case 0: //Main menu
		for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
		{
			this->m_menuButtons[i].m_uiComp->UpdateHover(mousePos);
			if (this->m_menuButtons[i].m_uiComp->isHovered)
			{
				this->m_menuButtons[i].SetHovered(true);
				this->markedItem = i;
			}
			else if (i != this->markedItem)
			{
				this->m_menuButtons[i].SetHovered(false);
			}
		}

		if (inputHandler->IsMouseKeyReleased(SDL_BUTTON_LEFT))
		{
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].m_uiComp->UpdateClicked(mousePos);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_RETURN))
		{
			this->m_menuButtons[markedItem].m_uiComp->wasClicked = true;
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_DOWN))
		{
			if (this->markedItem < this->m_NR_OF_MAIN_MENU_ITEMS - 1)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem++;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_UP))
		{
			if (this->markedItem > 0)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem--;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}

		if (this->m_menuButtons[0].m_uiComp->CheckClicked())
		{
			//Start game was clicked

			//Create, Initialize and push a LevelSelectState
			LevelSelectState* levelSelect = new LevelSelectState();
			result = levelSelect->Initialize(this->m_gsh, this->m_cHandlerPtr, this->m_cameraRef);

			//If the initialization was successful
			if (result > 0)
			{
				//Push it to the gamestate stack/vector
				this->m_gsh->PushStateToStack(levelSelect);

				levelSelect->LoadLevel(std::string("../ResourceLib/AssetFiles/TestingLevel.level"));
			}
			else
			{
				//Delete it
				delete levelSelect;
				levelSelect = nullptr;
			}

			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
		}
		else if (this->m_menuButtons[1].m_uiComp->CheckClicked())
		{
			//Options was clicked
			this->m_menuButtons[this->markedItem].SetHovered(false);
			this->markedItem = this->m_NR_OF_MAIN_MENU_ITEMS;
			this->m_menuButtons[this->m_NR_OF_MAIN_MENU_ITEMS].SetHovered(true);
			this->menuState = 1;
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(true);
			}
		}
		else if (this->m_menuButtons[2].m_uiComp->CheckClicked())
		{
			//Quit game was clicked
			result = 0;
		}
		break;

	case 1: //Options Menu
		for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_OPTIONS_MENU_ITEMS; i++)
		{
			this->m_menuButtons[i].m_uiComp->UpdateHover(mousePos);
			if (this->m_menuButtons[i].m_uiComp->isHovered)
			{
				this->m_menuButtons[i].SetHovered(true);
				this->markedItem = i;
			}
			else if (i != this->markedItem)
			{
				this->m_menuButtons[i].SetHovered(false);
			}
		}

		if (inputHandler->IsMouseKeyReleased(SDL_BUTTON_LEFT))
		{
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_OPTIONS_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].m_uiComp->UpdateClicked(mousePos);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_RETURN))
		{
			this->m_menuButtons[markedItem].m_uiComp->wasClicked = true;
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_DOWN))
		{
			if (this->markedItem < this->m_NR_OF_MENU_ITEMS - 1)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem++;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}
		if (inputHandler->IsKeyPressed(SDL_SCANCODE_UP))
		{
			if (this->markedItem > this->m_NR_OF_MAIN_MENU_ITEMS)
			{
				this->m_menuButtons[this->markedItem].SetHovered(false);
				this->markedItem--;
				this->m_menuButtons[this->markedItem].SetHovered(true);
			}
		}

		if (this->m_menuButtons[3].m_uiComp->CheckClicked())
		{
			//Toggle fullscreen was clicked
			//Cheating by telling the system the user pressed F
			inputHandler->SetKeyState(SDL_SCANCODE_F, true); //Seems this does not reset, ever
		}
		else if (this->m_menuButtons[4].m_uiComp->CheckClicked())
		{
			//Return to main menu was clicked
			inputHandler->SetKeyState(SDL_SCANCODE_F, false); //Temporary cheat
			this->m_menuButtons[this->markedItem].SetHovered(false);
			this->markedItem = 0;
			this->m_menuButtons[0].SetHovered(true);
			this->menuState = 0;
			for (size_t i = 0; i < m_NR_OF_MAIN_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(true);
			}
			for (size_t i = m_NR_OF_MAIN_MENU_ITEMS; i < m_NR_OF_MENU_ITEMS; i++)
			{
				this->m_menuButtons[i].SetActive(false);
			}
		}

		break;
	default:
		break;
	}

	return result;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.1  2002/02/01 22:22:11  peiyongz
 * Initial revision
 *
 * Revision 1.8  2001/12/06 17:48:36  tng
 * Performance Enhancement.  Added setNPrefix and setNLocalPart methods that allow code to take advantage of the fact that it knows the length of the prefix and local name, when possible.  That can avoid a copy of the prefix into a null-terminated temporary variable before copying into the fPrefix.
 * Also changed the getRawName method so that it would simply return the local part when there is no prefix, instead of allocating another buffer to copy the local part into the fRawName.
 * When there is a prefix, changed the getRawName to copy the prefix and local part into the fRawName using XMLString::moveChars instead of using XMLString::copyString and XMLString::catString.  The catString method has to loop past the prefix portion of the fRawName, which seems like a waste.
 * By Henry Zongaro.
 *
 * Revision 1.7  2001/07/24 18:31:47  knoaman
 * Added support for <group> + extra constraint checking for complexType
 *
 * Revision 1.6  2001/05/11 13:26:28  tng
 * Copyright update.
 *
 * Revision 1.5  2001/04/19 18:17:08  tng
 * Schema: SchemaValidator update, and use QName in Content Model
 *
 * Revision 1.4  2001/03/21 21:56:11  tng
 * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
 *
 * Revision 1.3  2001/02/27 14:48:35  tng
 * Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
 *
 * Revision 1.2  2001/02/26 21:56:15  tng
 * Schema: QName can also be constructed with rawName.
 *
 * Revision 1.1  2001/02/26 19:44:25  tng
 * Schema: add utility class QName, by Pei Yong Zhang.
 *
 */

#include <xercesc/util/QName.hpp>
#include <xercesc/util/Janitor.hpp>

// ---------------------------------------------------------------------------
//  QName: Constructors and Destructor
// ---------------------------------------------------------------------------
QName::QName() :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
}

QName::QName(const XMLCh* const        prefix
           , const XMLCh* const        localPart
           , const unsigned int        uriId
            ) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    try
    {
        //
        //  Just call the local setters to set up everything. Too much
        //  work is required to replicate that functionality here.
        //
        setName(prefix, localPart, uriId);
    }

    catch(...)
    {
        cleanUp();
    }
}

QName::QName(const XMLCh* const        rawName
           , const unsigned int        uriId
            ) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    try
    {
        //
        //  Just call the local setters to set up everything. Too much
        //  work is required to replicate that functionality here.
        //
        setName(rawName, uriId);
    }

    catch(...)
    {
        cleanUp();
    }
}

QName::~QName()
{
	cleanUp();
}

// ---------------------------------------------------------------------------
//  QName: Copy Constructors
// ---------------------------------------------------------------------------
QName::QName(const QName* const qname) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(qname->getLocalPart());
    fLocalPartBufSz = newLen + 8;
    fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    XMLString::moveChars(fLocalPart, qname->getLocalPart(), newLen + 1);

    newLen = XMLString::stringLen(qname->getPrefix());
    fPrefixBufSz = newLen + 8;
    fPrefix = new XMLCh[fPrefixBufSz + 1];
    XMLString::moveChars(fPrefix, qname->getPrefix(), newLen + 1);

    fURIId = qname->getURI();
}

// ---------------------------------------------------------------------------
//  QName: Getter methods
// ---------------------------------------------------------------------------
const XMLCh* QName::getRawName() const
{
    //
    //  If there is no buffer, or if there is but we've not faulted in the
    //  value yet, then we have to do that now.
    //
    if (!fRawName || !*fRawName)
    {
        //
        //  If we have a prefix, then do the prefix:name version. Else, its
        //  just the name.
        //
        if (*fPrefix)
        {
            //
            //  Calculate the worst case size buffer we will need. We use the
            //  current high water marks of the prefix and name buffers, so it
            //  might be a little wasteful of memory but we don't have to do
            //  string len operations on the two strings.
            //
            const unsigned int neededLen = fPrefixBufSz + fLocalPartBufSz + 1;

            //
            //  If no buffer, or the current one is too small, then allocate one
            //  and get rid of any old one.
            //
            if (!fRawName || (neededLen > fRawNameBufSz))
            {
                delete [] fRawName;

                // We have to cast off the const'ness to do this
                ((QName*)this)->fRawNameBufSz = neededLen;
                ((QName*)this)->fRawName = new XMLCh[neededLen + 1];

                // Make sure its initially empty
                *fRawName = 0;
            }

            const unsigned int prefixLen = XMLString::stringLen(fPrefix);

            XMLString::moveChars(fRawName, fPrefix, prefixLen);
            fRawName[prefixLen] = chColon;
            XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
        }
         else
        {
            return fLocalPart;
        }
    }
    return fRawName;
}

XMLCh* QName::getRawName()
{
    //
    //  If there is no buffer, or if there is but we've not faulted in the
    //  value yet, then we have to do that now.
    //
    if (!fRawName || !*fRawName)
    {
        //
        //  If we have a prefix, then do the prefix:name version. Else, its
        //  just the name.
        //
        if (*fPrefix)
        {
            //
            //  Calculate the worst case size buffer we will need. We use the
            //  current high water marks of the prefix and name buffers, so it
            //  might be a little wasteful of memory but we don't have to do
            //  string len operations on the two strings.
            //
            const unsigned int neededLen = fPrefixBufSz + fLocalPartBufSz + 1;

            //
            //  If no buffer, or the current one is too small, then allocate one
            //  and get rid of any old one.
            //
            if (!fRawName || (neededLen > fRawNameBufSz))
            {
                delete [] fRawName;

                // We have to cast off the const'ness to do this
                ((QName*)this)->fRawNameBufSz = neededLen;
                ((QName*)this)->fRawName = new XMLCh[neededLen + 1];

                // Make sure its initially empty
                *fRawName = 0;
            }

            const unsigned int prefixLen = XMLString::stringLen(fPrefix);

            XMLString::moveChars(fRawName, fPrefix, prefixLen);
            fRawName[prefixLen] = chColon;
            XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
        }
         else
        {
            return fLocalPart;
        }
    }
    return fRawName;
}

// ---------------------------------------------------------------------------
//  QName: Setter methods
// ---------------------------------------------------------------------------
void QName::setName(const XMLCh* const    prefix
                  , const XMLCh* const    localPart
                  , const unsigned int    uriId)
{
    setPrefix(prefix);
    setLocalPart(localPart);

    // And clean up any QName and leave it undone until/if asked for again
    if (fRawName)
        *fRawName = 0;

    // And finally store the URI id parameter
    fURIId = uriId;
}

void QName::setName(const XMLCh* const    rawName
                  , const unsigned int    uriId)
{
    //set the rawName
    unsigned int newLen;

    newLen = XMLString::stringLen(rawName);
    if (!fRawNameBufSz || (newLen > fRawNameBufSz))
    {
        delete [] fRawName;
        fRawNameBufSz = newLen + 8;
        fRawName = new XMLCh[fRawNameBufSz + 1];
    }
    XMLString::moveChars(fRawName, rawName, newLen + 1);

    //find out the prefix and localPart from the rawName
    const int colonInd = XMLString::indexOf(rawName, chColon);
    if (colonInd >= 0)
    {
        setNPrefix(rawName, colonInd);
    }
     else
    {
        // No colon, so we just have a name with no prefix
        setPrefix(XMLUni::fgZeroLenString);
    }

    setNLocalPart(&rawName[colonInd+1], newLen-colonInd-1);

    // And finally store the URI id parameter
    fURIId = uriId;
}

void QName::setPrefix(const XMLCh* prefix)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(prefix);
    if (!fPrefixBufSz || (newLen > fPrefixBufSz))
    {
        delete [] fPrefix;
        fPrefixBufSz = newLen + 8;
        fPrefix = new XMLCh[fPrefixBufSz + 1];
    }
    XMLString::moveChars(fPrefix, prefix, newLen + 1);
}

void QName::setNPrefix(const XMLCh* prefix, const unsigned int newLen)
{
    if (!fPrefixBufSz || (newLen > fPrefixBufSz))
    {
        delete [] fPrefix;
        fPrefixBufSz = newLen + 8;
        fPrefix = new XMLCh[fPrefixBufSz + 1];
    }
    XMLString::moveChars(fPrefix, prefix, newLen);
    fPrefix[newLen] = chNull;
}

void QName::setLocalPart(const XMLCh* localPart)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(localPart);
    if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
    {
        delete [] fLocalPart;
        fLocalPartBufSz = newLen + 8;
        fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    }
    XMLString::moveChars(fLocalPart, localPart, newLen + 1);
}

void QName::setNLocalPart(const XMLCh* localPart, const unsigned int newLen)
{
    if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
    {
        delete [] fLocalPart;
        fLocalPartBufSz = newLen + 8;
        fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    }
    XMLString::moveChars(fLocalPart, localPart, newLen);
    fLocalPart[newLen] = chNull;
}

void QName::setValues(const QName& qname)
{
    setPrefix(qname.getPrefix());
    setLocalPart(qname.getLocalPart());
    setURI(qname.getURI());
}

// -----------------------------------------------------------------------
//  comparison
// -----------------------------------------------------------------------
bool QName::operator==(const QName& qname)
{
return (XMLString::compareString(fPrefix, qname.getPrefix())==0) &&
       (XMLString::compareString(fLocalPart, qname.getLocalPart())==0) &&
       (fURIId == qname.getURI());
}

// ---------------------------------------------------------------------------
//  QName: Private, helper methods
// ---------------------------------------------------------------------------
void QName::cleanUp()
{
    delete [] fLocalPart;
    delete [] fPrefix;
    delete [] fRawName;
}

<commit_msg>Modiy QName comparison (operator=).<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.2  2002/04/02 15:31:48  knoaman
 * Modiy QName comparison (operator=).
 *
 * Revision 1.1.1.1  2002/02/01 22:22:11  peiyongz
 * sane_include
 *
 * Revision 1.8  2001/12/06 17:48:36  tng
 * Performance Enhancement.  Added setNPrefix and setNLocalPart methods that allow code to take advantage of the fact that it knows the length of the prefix and local name, when possible.  That can avoid a copy of the prefix into a null-terminated temporary variable before copying into the fPrefix.
 * Also changed the getRawName method so that it would simply return the local part when there is no prefix, instead of allocating another buffer to copy the local part into the fRawName.
 * When there is a prefix, changed the getRawName to copy the prefix and local part into the fRawName using XMLString::moveChars instead of using XMLString::copyString and XMLString::catString.  The catString method has to loop past the prefix portion of the fRawName, which seems like a waste.
 * By Henry Zongaro.
 *
 * Revision 1.7  2001/07/24 18:31:47  knoaman
 * Added support for <group> + extra constraint checking for complexType
 *
 * Revision 1.6  2001/05/11 13:26:28  tng
 * Copyright update.
 *
 * Revision 1.5  2001/04/19 18:17:08  tng
 * Schema: SchemaValidator update, and use QName in Content Model
 *
 * Revision 1.4  2001/03/21 21:56:11  tng
 * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
 *
 * Revision 1.3  2001/02/27 14:48:35  tng
 * Schema: Add CMAny and ContentLeafNameTypeVector, by Pei Yong Zhang
 *
 * Revision 1.2  2001/02/26 21:56:15  tng
 * Schema: QName can also be constructed with rawName.
 *
 * Revision 1.1  2001/02/26 19:44:25  tng
 * Schema: add utility class QName, by Pei Yong Zhang.
 *
 */

#include <xercesc/util/QName.hpp>
#include <xercesc/util/Janitor.hpp>

// ---------------------------------------------------------------------------
//  QName: Constructors and Destructor
// ---------------------------------------------------------------------------
QName::QName() :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
}

QName::QName(const XMLCh* const        prefix
           , const XMLCh* const        localPart
           , const unsigned int        uriId
            ) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    try
    {
        //
        //  Just call the local setters to set up everything. Too much
        //  work is required to replicate that functionality here.
        //
        setName(prefix, localPart, uriId);
    }

    catch(...)
    {
        cleanUp();
    }
}

QName::QName(const XMLCh* const        rawName
           , const unsigned int        uriId
            ) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    try
    {
        //
        //  Just call the local setters to set up everything. Too much
        //  work is required to replicate that functionality here.
        //
        setName(rawName, uriId);
    }

    catch(...)
    {
        cleanUp();
    }
}

QName::~QName()
{
	cleanUp();
}

// ---------------------------------------------------------------------------
//  QName: Copy Constructors
// ---------------------------------------------------------------------------
QName::QName(const QName* const qname) :
      fPrefix(0)
    , fPrefixBufSz(0)
    , fLocalPart(0)
    , fLocalPartBufSz(0)
    , fRawName(0)
    , fRawNameBufSz(0)
    , fURIId(0)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(qname->getLocalPart());
    fLocalPartBufSz = newLen + 8;
    fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    XMLString::moveChars(fLocalPart, qname->getLocalPart(), newLen + 1);

    newLen = XMLString::stringLen(qname->getPrefix());
    fPrefixBufSz = newLen + 8;
    fPrefix = new XMLCh[fPrefixBufSz + 1];
    XMLString::moveChars(fPrefix, qname->getPrefix(), newLen + 1);

    fURIId = qname->getURI();
}

// ---------------------------------------------------------------------------
//  QName: Getter methods
// ---------------------------------------------------------------------------
const XMLCh* QName::getRawName() const
{
    //
    //  If there is no buffer, or if there is but we've not faulted in the
    //  value yet, then we have to do that now.
    //
    if (!fRawName || !*fRawName)
    {
        //
        //  If we have a prefix, then do the prefix:name version. Else, its
        //  just the name.
        //
        if (*fPrefix)
        {
            //
            //  Calculate the worst case size buffer we will need. We use the
            //  current high water marks of the prefix and name buffers, so it
            //  might be a little wasteful of memory but we don't have to do
            //  string len operations on the two strings.
            //
            const unsigned int neededLen = fPrefixBufSz + fLocalPartBufSz + 1;

            //
            //  If no buffer, or the current one is too small, then allocate one
            //  and get rid of any old one.
            //
            if (!fRawName || (neededLen > fRawNameBufSz))
            {
                delete [] fRawName;

                // We have to cast off the const'ness to do this
                ((QName*)this)->fRawNameBufSz = neededLen;
                ((QName*)this)->fRawName = new XMLCh[neededLen + 1];

                // Make sure its initially empty
                *fRawName = 0;
            }

            const unsigned int prefixLen = XMLString::stringLen(fPrefix);

            XMLString::moveChars(fRawName, fPrefix, prefixLen);
            fRawName[prefixLen] = chColon;
            XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
        }
         else
        {
            return fLocalPart;
        }
    }
    return fRawName;
}

XMLCh* QName::getRawName()
{
    //
    //  If there is no buffer, or if there is but we've not faulted in the
    //  value yet, then we have to do that now.
    //
    if (!fRawName || !*fRawName)
    {
        //
        //  If we have a prefix, then do the prefix:name version. Else, its
        //  just the name.
        //
        if (*fPrefix)
        {
            //
            //  Calculate the worst case size buffer we will need. We use the
            //  current high water marks of the prefix and name buffers, so it
            //  might be a little wasteful of memory but we don't have to do
            //  string len operations on the two strings.
            //
            const unsigned int neededLen = fPrefixBufSz + fLocalPartBufSz + 1;

            //
            //  If no buffer, or the current one is too small, then allocate one
            //  and get rid of any old one.
            //
            if (!fRawName || (neededLen > fRawNameBufSz))
            {
                delete [] fRawName;

                // We have to cast off the const'ness to do this
                ((QName*)this)->fRawNameBufSz = neededLen;
                ((QName*)this)->fRawName = new XMLCh[neededLen + 1];

                // Make sure its initially empty
                *fRawName = 0;
            }

            const unsigned int prefixLen = XMLString::stringLen(fPrefix);

            XMLString::moveChars(fRawName, fPrefix, prefixLen);
            fRawName[prefixLen] = chColon;
            XMLString::copyString(&fRawName[prefixLen+1], fLocalPart);
        }
         else
        {
            return fLocalPart;
        }
    }
    return fRawName;
}

// ---------------------------------------------------------------------------
//  QName: Setter methods
// ---------------------------------------------------------------------------
void QName::setName(const XMLCh* const    prefix
                  , const XMLCh* const    localPart
                  , const unsigned int    uriId)
{
    setPrefix(prefix);
    setLocalPart(localPart);

    // And clean up any QName and leave it undone until/if asked for again
    if (fRawName)
        *fRawName = 0;

    // And finally store the URI id parameter
    fURIId = uriId;
}

void QName::setName(const XMLCh* const    rawName
                  , const unsigned int    uriId)
{
    //set the rawName
    unsigned int newLen;

    newLen = XMLString::stringLen(rawName);
    if (!fRawNameBufSz || (newLen > fRawNameBufSz))
    {
        delete [] fRawName;
        fRawNameBufSz = newLen + 8;
        fRawName = new XMLCh[fRawNameBufSz + 1];
    }
    XMLString::moveChars(fRawName, rawName, newLen + 1);

    //find out the prefix and localPart from the rawName
    const int colonInd = XMLString::indexOf(rawName, chColon);
    if (colonInd >= 0)
    {
        setNPrefix(rawName, colonInd);
    }
     else
    {
        // No colon, so we just have a name with no prefix
        setPrefix(XMLUni::fgZeroLenString);
    }

    setNLocalPart(&rawName[colonInd+1], newLen-colonInd-1);

    // And finally store the URI id parameter
    fURIId = uriId;
}

void QName::setPrefix(const XMLCh* prefix)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(prefix);
    if (!fPrefixBufSz || (newLen > fPrefixBufSz))
    {
        delete [] fPrefix;
        fPrefixBufSz = newLen + 8;
        fPrefix = new XMLCh[fPrefixBufSz + 1];
    }
    XMLString::moveChars(fPrefix, prefix, newLen + 1);
}

void QName::setNPrefix(const XMLCh* prefix, const unsigned int newLen)
{
    if (!fPrefixBufSz || (newLen > fPrefixBufSz))
    {
        delete [] fPrefix;
        fPrefixBufSz = newLen + 8;
        fPrefix = new XMLCh[fPrefixBufSz + 1];
    }
    XMLString::moveChars(fPrefix, prefix, newLen);
    fPrefix[newLen] = chNull;
}

void QName::setLocalPart(const XMLCh* localPart)
{
    unsigned int newLen;

    newLen = XMLString::stringLen(localPart);
    if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
    {
        delete [] fLocalPart;
        fLocalPartBufSz = newLen + 8;
        fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    }
    XMLString::moveChars(fLocalPart, localPart, newLen + 1);
}

void QName::setNLocalPart(const XMLCh* localPart, const unsigned int newLen)
{
    if (!fLocalPartBufSz || (newLen > fLocalPartBufSz))
    {
        delete [] fLocalPart;
        fLocalPartBufSz = newLen + 8;
        fLocalPart = new XMLCh[fLocalPartBufSz + 1];
    }
    XMLString::moveChars(fLocalPart, localPart, newLen);
    fLocalPart[newLen] = chNull;
}

void QName::setValues(const QName& qname)
{
    setPrefix(qname.getPrefix());
    setLocalPart(qname.getLocalPart());
    setURI(qname.getURI());
}

// -----------------------------------------------------------------------
//  comparison
// -----------------------------------------------------------------------
bool QName::operator==(const QName& qname)
{
    if (fURIId == 0) // null URI
        return (XMLString::compareString(getRawName(),qname.getRawName())==0);

    return ((fURIId == qname.getURI()) &&
           (XMLString::compareString(fLocalPart, qname.getLocalPart())==0));
}

// ---------------------------------------------------------------------------
//  QName: Private, helper methods
// ---------------------------------------------------------------------------
void QName::cleanUp()
{
    delete [] fLocalPart;
    delete [] fPrefix;
    delete [] fRawName;
}

<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#include "QOSPRayWindow.h"
#include "modules/opengl/util.h"

#ifdef __APPLE__
  #include <OpenGL/glu.h>
#else
  #include <GL/glu.h>
#endif

QOSPRayWindow::QOSPRayWindow(QMainWindow *parent,
                             OSPRenderer renderer,
                             bool showFrameRate,
                             std::string writeFramesFilename)
  : parent(parent),
    showFrameRate(showFrameRate),
    frameCount(0),
    renderingEnabled(false),
    rotationRate(0.f),
    benchmarkWarmUpFrames(0),
    benchmarkFrames(0),
    frameBuffer(NULL),
    renderer(NULL),
    camera(NULL),
    maxDepthTexture(NULL),
    writeFramesFilename(writeFramesFilename)
{
  // assign renderer
  if(!renderer)
    throw std::runtime_error("QOSPRayWindow: must be constructed with an existing renderer");

  this->renderer = renderer;

  // setup camera
  camera = ospNewCamera("perspective");

  if(!camera)
    throw std::runtime_error("QOSPRayWindow: could not create camera type 'perspective'");

  ospCommit(camera);

  ospSetObject(renderer, "camera", camera);

  // connect signals and slots
  connect(&renderTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
  connect(&renderRestartTimer, SIGNAL(timeout()), &renderTimer, SLOT(start()));
}

QOSPRayWindow::~QOSPRayWindow()
{
  // free the frame buffer and camera
  // we don't own the renderer!
  if(frameBuffer)
    ospFreeFrameBuffer(frameBuffer);

  if(camera)
    ospRelease(camera);
}

void QOSPRayWindow::setRenderingEnabled(bool renderingEnabled)
{
  this->renderingEnabled = renderingEnabled;

  // trigger render if true
  if(renderingEnabled == true)
    renderTimer.start();
  else
    renderTimer.stop();
}

void QOSPRayWindow::setRotationRate(float rotationRate)
{
  this->rotationRate = rotationRate;
}

void QOSPRayWindow::setBenchmarkParameters(int benchmarkWarmUpFrames, int benchmarkFrames)
{
  this->benchmarkWarmUpFrames = benchmarkWarmUpFrames;
  this->benchmarkFrames = benchmarkFrames;
}

void QOSPRayWindow::setWorldBounds(const osp::box3f &worldBounds)
{
  this->worldBounds = worldBounds;

  // set viewport look at point to center of world bounds
  viewport.at = center(worldBounds);

  // set viewport from point relative to center of world bounds
  viewport.from = viewport.at - 1.5f * length(worldBounds.size()) * viewport.frame.l.vy;

  updateGL();
}

void QOSPRayWindow::paintGL()
{
  if(!renderingEnabled || !frameBuffer || !renderer)
    return;

  // if we're benchmarking and we've completed the required number of warm-up frames, start the timer
  if(benchmarkFrames > 0 && frameCount == benchmarkWarmUpFrames) {
    std::cout << "starting benchmark timer" << std::endl;
    benchmarkTimer.start();
  }

  // update OSPRay camera if viewport has been modified
  if(viewport.modified) {
    ospSetVec3f(camera,"pos" ,viewport.from);
    ospSetVec3f(camera,"dir" ,viewport.at - viewport.from);
    ospSetVec3f(camera,"up", viewport.up);
    ospSetf(camera,"aspect", viewport.aspect);
    ospSetf(camera,"fovy", viewport.fovY);

    ospCommit(camera);

    viewport.modified = false;
  }

  renderFrameTimer.start();

  // we have OpenGL components if any slots are connected to the renderGLComponents() signal
  // if so, render these first and then composite the OSPRay-rendered content on top
  bool haveOpenGLComponents = receivers(SIGNAL(renderGLComponents())) > 0;

  if (haveOpenGLComponents) {

    // setup OpenGL view to match current view and render all OpenGL components
    renderGL();

    // generate max depth texture for early ray termination
    if (maxDepthTexture)
      ospRelease(maxDepthTexture);

    maxDepthTexture = ospray::opengl::getOSPDepthTextureFromOpenGLPerspective();
    ospSetObject(renderer, "maxDepthTexture", maxDepthTexture);

    // disable OSPRay background rendering since we're compositing
    ospSet1i(renderer, "backgroundEnabled", 0);

    ospCommit(renderer);

    // disable OpenGL depth testing and enable blending for compositing
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }
  else {

    // unset any maximum depth texture and enable OSPRay background rendering
    ospSetObject(renderer, "maxDepthTexture", NULL);
    ospSet1i(renderer, "backgroundEnabled", 1);
    ospCommit(renderer);

    // disable OpenGL blending
    glDisable(GL_BLEND);
  }

  ospRenderFrame(frameBuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
  double framesPerSecond = 1000.0 / renderFrameTimer.elapsed();
  char title[1024];  sprintf(title, "OSPRay Volume Viewer (%.4f fps)", framesPerSecond);
  if (showFrameRate == true) parent->setWindowTitle(title);

  uint32 *mappedFrameBuffer = (unsigned int *) ospMapFrameBuffer(frameBuffer);

  glDrawPixels(windowSize.x, windowSize.y, GL_RGBA, GL_UNSIGNED_BYTE, mappedFrameBuffer);
  if (writeFramesFilename.length()) writeFrameBufferToFile(mappedFrameBuffer);

  ospUnmapFrameBuffer(mappedFrameBuffer, frameBuffer);

  // automatic rotation
  if(rotationRate != 0.f) {
    resetAccumulationBuffer();
    rotateCenter(rotationRate, 0.f);
  }

  // increment frame counter
  frameCount++;

  // quit if we're benchmarking and have exceeded the needed number of frames
  if(benchmarkFrames > 0 && frameCount >= benchmarkWarmUpFrames + benchmarkFrames) {

    float elapsedSeconds = float(benchmarkTimer.elapsed()) / 1000.f;

    std::cout << "benchmark: " << elapsedSeconds << " elapsed seconds ==> " << float(benchmarkFrames) / elapsedSeconds << " fps" << std::endl;

    QCoreApplication::quit();
  }
}

void QOSPRayWindow::resizeGL(int width, int height)
{
  windowSize = osp::vec2i(width, height);

  // reallocate OSPRay framebuffer for new size
  if(frameBuffer)
    ospFreeFrameBuffer(frameBuffer);

  frameBuffer = ospNewFrameBuffer(windowSize, OSP_RGBA_I8, OSP_FB_COLOR | OSP_FB_ACCUM);

  // set gamma correction
  ospSet1f(frameBuffer, "gamma", 2.2f);
  ospCommit(frameBuffer);

  resetAccumulationBuffer();

  // update viewport aspect ratio
  viewport.aspect = float(width) / float(height);
  viewport.modified = true;

  // update OpenGL viewport and force redraw
  glViewport(0, 0, width, height);
  updateGL();
}

void QOSPRayWindow::mousePressEvent(QMouseEvent * event)
{
  lastMousePosition = event->pos();
}

void QOSPRayWindow::mouseReleaseEvent(QMouseEvent * event)
{
  lastMousePosition = event->pos();

  // restart continuous rendering immediately
  renderTimer.start();
}

void QOSPRayWindow::mouseMoveEvent(QMouseEvent * event)
{
  // pause continuous rendering during interaction and cancel any render restart timers.
  // this keeps interaction more responsive (especially with low frame rates).
  renderTimer.stop();
  renderRestartTimer.stop();

  resetAccumulationBuffer();

  int dx = event->x() - lastMousePosition.x();
  int dy = event->y() - lastMousePosition.y();

  if(event->buttons() & Qt::LeftButton) {

    // camera rotation about center point
    const float rotationSpeed = 0.003f;

    float du = dx * rotationSpeed;
    float dv = dy * rotationSpeed;

    rotateCenter(du, dv);
  }
  else if(event->buttons() & Qt::MidButton) {

    // camera strafe of from / at point
    const float strafeSpeed = 0.001f * length(worldBounds.size());

    float du = dx * strafeSpeed;
    float dv = dy * strafeSpeed;

    strafe(du, dv);
  }
  else if(event->buttons() & Qt::RightButton) {

    // camera distance from center point
    const float motionSpeed = 0.012f;

    float forward = dy * motionSpeed * length(worldBounds.size());
    float oldDistance = length(viewport.at - viewport.from);
    float newDistance = oldDistance - forward;

    if(newDistance < 1e-3f)
      return;

    viewport.from = viewport.at - newDistance * viewport.frame.l.vy;
    viewport.frame.p = viewport.from;

    viewport.modified = true;
  }

  lastMousePosition = event->pos();

  updateGL();

  // after a 0.5s delay, restart continuous rendering.
  renderRestartTimer.setSingleShot(true);
  renderRestartTimer.start(500);
}

void QOSPRayWindow::rotateCenter(float du, float dv)
{
  const osp::vec3f pivot = viewport.at;

  osp::affine3f xfm = osp::affine3f::translate(pivot)
    * osp::affine3f::rotate(viewport.frame.l.vx, -dv)
    * osp::affine3f::rotate(viewport.frame.l.vz, -du)
    * osp::affine3f::translate(-pivot);

  viewport.frame = xfm * viewport.frame;
  viewport.from  = xfmPoint(xfm, viewport.from);
  viewport.at    = xfmPoint(xfm, viewport.at);
  viewport.snapUp();

  viewport.modified = true;
}

void QOSPRayWindow::strafe(float du, float dv)
{
  osp::affine3f xfm = osp::affine3f::translate(dv * viewport.frame.l.vz)
    * osp::affine3f::translate(-du * viewport.frame.l.vx);

  viewport.frame = xfm * viewport.frame;
  viewport.from = xfmPoint(xfm, viewport.from);
  viewport.at = xfmPoint(xfm, viewport.at);
  viewport.modified = true;

  viewport.modified = true;
}

void QOSPRayWindow::renderGL()
{
  // setup OpenGL state to match OSPRay view
  const osp::vec3f bgColor = osp::vec3f(1.f);
  glClearColor(bgColor.x, bgColor.y, bgColor.z, 1.f);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  float zNear = 0.1f;
  float zFar = 100000.f;
  gluPerspective(viewport.fovY, viewport.aspect, zNear, zFar);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(viewport.from.x, viewport.from.y, viewport.from.z,
            viewport.at.x, viewport.at.y, viewport.at.z,
            viewport.up.x, viewport.up.y, viewport.up.z);

  // emit signal to render all OpenGL components; the slots will execute in the order they were registered
  emit(renderGLComponents());
}

void QOSPRayWindow::writeFrameBufferToFile(const uint32 *pixelData)
{
  static uint32 frameNumber = 0;
  char filename[1024];
  sprintf(filename, "%s_%05u.ppm", writeFramesFilename.c_str(), frameNumber++);
  FILE *file = fopen(filename, "wb");  if (!file) { std::cerr << "unable to write to file '" << filename << "'" << std::endl;  return; }

  fprintf(file, "P6\n%i %i\n255\n", windowSize.x, windowSize.y);
  unsigned char out[3 * windowSize.x];
  for (int y=0 ; y < windowSize.y ; y++) {
    const unsigned char *in = (const unsigned char *) &pixelData[(windowSize.y - 1 - y) * windowSize.x];
    for (int x=0 ; x < windowSize.x ; x++) {
      out[3 * x + 0] = in[4 * x + 0];
      out[3 * x + 1] = in[4 * x + 1];
      out[3 * x + 2] = in[4 * x + 2];
    }
    fwrite(&out, 3 * windowSize.x, sizeof(char), file);
  }
  fprintf(file, "\n");
  fclose(file);
}
<commit_msg>volume viewer gamma correction disabled.<commit_after>// ======================================================================== //
// Copyright 2009-2015 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

#include "QOSPRayWindow.h"
#include "modules/opengl/util.h"

#ifdef __APPLE__
  #include <OpenGL/glu.h>
#else
  #include <GL/glu.h>
#endif

QOSPRayWindow::QOSPRayWindow(QMainWindow *parent,
                             OSPRenderer renderer,
                             bool showFrameRate,
                             std::string writeFramesFilename)
  : parent(parent),
    showFrameRate(showFrameRate),
    frameCount(0),
    renderingEnabled(false),
    rotationRate(0.f),
    benchmarkWarmUpFrames(0),
    benchmarkFrames(0),
    frameBuffer(NULL),
    renderer(NULL),
    camera(NULL),
    maxDepthTexture(NULL),
    writeFramesFilename(writeFramesFilename)
{
  // assign renderer
  if(!renderer)
    throw std::runtime_error("QOSPRayWindow: must be constructed with an existing renderer");

  this->renderer = renderer;

  // setup camera
  camera = ospNewCamera("perspective");

  if(!camera)
    throw std::runtime_error("QOSPRayWindow: could not create camera type 'perspective'");

  ospCommit(camera);

  ospSetObject(renderer, "camera", camera);

  // connect signals and slots
  connect(&renderTimer, SIGNAL(timeout()), this, SLOT(updateGL()));
  connect(&renderRestartTimer, SIGNAL(timeout()), &renderTimer, SLOT(start()));
}

QOSPRayWindow::~QOSPRayWindow()
{
  // free the frame buffer and camera
  // we don't own the renderer!
  if(frameBuffer)
    ospFreeFrameBuffer(frameBuffer);

  if(camera)
    ospRelease(camera);
}

void QOSPRayWindow::setRenderingEnabled(bool renderingEnabled)
{
  this->renderingEnabled = renderingEnabled;

  // trigger render if true
  if(renderingEnabled == true)
    renderTimer.start();
  else
    renderTimer.stop();
}

void QOSPRayWindow::setRotationRate(float rotationRate)
{
  this->rotationRate = rotationRate;
}

void QOSPRayWindow::setBenchmarkParameters(int benchmarkWarmUpFrames, int benchmarkFrames)
{
  this->benchmarkWarmUpFrames = benchmarkWarmUpFrames;
  this->benchmarkFrames = benchmarkFrames;
}

void QOSPRayWindow::setWorldBounds(const osp::box3f &worldBounds)
{
  this->worldBounds = worldBounds;

  // set viewport look at point to center of world bounds
  viewport.at = center(worldBounds);

  // set viewport from point relative to center of world bounds
  viewport.from = viewport.at - 1.5f * length(worldBounds.size()) * viewport.frame.l.vy;

  updateGL();
}

void QOSPRayWindow::paintGL()
{
  if(!renderingEnabled || !frameBuffer || !renderer)
    return;

  // if we're benchmarking and we've completed the required number of warm-up frames, start the timer
  if(benchmarkFrames > 0 && frameCount == benchmarkWarmUpFrames) {
    std::cout << "starting benchmark timer" << std::endl;
    benchmarkTimer.start();
  }

  // update OSPRay camera if viewport has been modified
  if(viewport.modified) {
    ospSetVec3f(camera,"pos" ,viewport.from);
    ospSetVec3f(camera,"dir" ,viewport.at - viewport.from);
    ospSetVec3f(camera,"up", viewport.up);
    ospSetf(camera,"aspect", viewport.aspect);
    ospSetf(camera,"fovy", viewport.fovY);

    ospCommit(camera);

    viewport.modified = false;
  }

  renderFrameTimer.start();

  // we have OpenGL components if any slots are connected to the renderGLComponents() signal
  // if so, render these first and then composite the OSPRay-rendered content on top
  bool haveOpenGLComponents = receivers(SIGNAL(renderGLComponents())) > 0;

  if (haveOpenGLComponents) {

    // setup OpenGL view to match current view and render all OpenGL components
    renderGL();

    // generate max depth texture for early ray termination
    if (maxDepthTexture)
      ospRelease(maxDepthTexture);

    maxDepthTexture = ospray::opengl::getOSPDepthTextureFromOpenGLPerspective();
    ospSetObject(renderer, "maxDepthTexture", maxDepthTexture);

    // disable OSPRay background rendering since we're compositing
    ospSet1i(renderer, "backgroundEnabled", 0);

    ospCommit(renderer);

    // disable OpenGL depth testing and enable blending for compositing
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  }
  else {

    // unset any maximum depth texture and enable OSPRay background rendering
    ospSetObject(renderer, "maxDepthTexture", NULL);
    ospSet1i(renderer, "backgroundEnabled", 1);
    ospCommit(renderer);

    // disable OpenGL blending
    glDisable(GL_BLEND);
  }

  ospRenderFrame(frameBuffer, renderer, OSP_FB_COLOR | OSP_FB_ACCUM);
  double framesPerSecond = 1000.0 / renderFrameTimer.elapsed();
  char title[1024];  sprintf(title, "OSPRay Volume Viewer (%.4f fps)", framesPerSecond);
  if (showFrameRate == true) parent->setWindowTitle(title);

  uint32 *mappedFrameBuffer = (unsigned int *) ospMapFrameBuffer(frameBuffer);

  glDrawPixels(windowSize.x, windowSize.y, GL_RGBA, GL_UNSIGNED_BYTE, mappedFrameBuffer);
  if (writeFramesFilename.length()) writeFrameBufferToFile(mappedFrameBuffer);

  ospUnmapFrameBuffer(mappedFrameBuffer, frameBuffer);

  // automatic rotation
  if(rotationRate != 0.f) {
    resetAccumulationBuffer();
    rotateCenter(rotationRate, 0.f);
  }

  // increment frame counter
  frameCount++;

  // quit if we're benchmarking and have exceeded the needed number of frames
  if(benchmarkFrames > 0 && frameCount >= benchmarkWarmUpFrames + benchmarkFrames) {

    float elapsedSeconds = float(benchmarkTimer.elapsed()) / 1000.f;

    std::cout << "benchmark: " << elapsedSeconds << " elapsed seconds ==> " << float(benchmarkFrames) / elapsedSeconds << " fps" << std::endl;

    QCoreApplication::quit();
  }
}

void QOSPRayWindow::resizeGL(int width, int height)
{
  windowSize = osp::vec2i(width, height);

  // reallocate OSPRay framebuffer for new size
  if(frameBuffer)
    ospFreeFrameBuffer(frameBuffer);

  frameBuffer = ospNewFrameBuffer(windowSize, OSP_RGBA_I8, OSP_FB_COLOR | OSP_FB_ACCUM);

  // set gamma correction
  ospSet1f(frameBuffer, "gamma", 1.0f);
  ospCommit(frameBuffer);

  resetAccumulationBuffer();

  // update viewport aspect ratio
  viewport.aspect = float(width) / float(height);
  viewport.modified = true;

  // update OpenGL viewport and force redraw
  glViewport(0, 0, width, height);
  updateGL();
}

void QOSPRayWindow::mousePressEvent(QMouseEvent * event)
{
  lastMousePosition = event->pos();
}

void QOSPRayWindow::mouseReleaseEvent(QMouseEvent * event)
{
  lastMousePosition = event->pos();

  // restart continuous rendering immediately
  renderTimer.start();
}

void QOSPRayWindow::mouseMoveEvent(QMouseEvent * event)
{
  // pause continuous rendering during interaction and cancel any render restart timers.
  // this keeps interaction more responsive (especially with low frame rates).
  renderTimer.stop();
  renderRestartTimer.stop();

  resetAccumulationBuffer();

  int dx = event->x() - lastMousePosition.x();
  int dy = event->y() - lastMousePosition.y();

  if(event->buttons() & Qt::LeftButton) {

    // camera rotation about center point
    const float rotationSpeed = 0.003f;

    float du = dx * rotationSpeed;
    float dv = dy * rotationSpeed;

    rotateCenter(du, dv);
  }
  else if(event->buttons() & Qt::MidButton) {

    // camera strafe of from / at point
    const float strafeSpeed = 0.001f * length(worldBounds.size());

    float du = dx * strafeSpeed;
    float dv = dy * strafeSpeed;

    strafe(du, dv);
  }
  else if(event->buttons() & Qt::RightButton) {

    // camera distance from center point
    const float motionSpeed = 0.012f;

    float forward = dy * motionSpeed * length(worldBounds.size());
    float oldDistance = length(viewport.at - viewport.from);
    float newDistance = oldDistance - forward;

    if(newDistance < 1e-3f)
      return;

    viewport.from = viewport.at - newDistance * viewport.frame.l.vy;
    viewport.frame.p = viewport.from;

    viewport.modified = true;
  }

  lastMousePosition = event->pos();

  updateGL();

  // after a 0.5s delay, restart continuous rendering.
  renderRestartTimer.setSingleShot(true);
  renderRestartTimer.start(500);
}

void QOSPRayWindow::rotateCenter(float du, float dv)
{
  const osp::vec3f pivot = viewport.at;

  osp::affine3f xfm = osp::affine3f::translate(pivot)
    * osp::affine3f::rotate(viewport.frame.l.vx, -dv)
    * osp::affine3f::rotate(viewport.frame.l.vz, -du)
    * osp::affine3f::translate(-pivot);

  viewport.frame = xfm * viewport.frame;
  viewport.from  = xfmPoint(xfm, viewport.from);
  viewport.at    = xfmPoint(xfm, viewport.at);
  viewport.snapUp();

  viewport.modified = true;
}

void QOSPRayWindow::strafe(float du, float dv)
{
  osp::affine3f xfm = osp::affine3f::translate(dv * viewport.frame.l.vz)
    * osp::affine3f::translate(-du * viewport.frame.l.vx);

  viewport.frame = xfm * viewport.frame;
  viewport.from = xfmPoint(xfm, viewport.from);
  viewport.at = xfmPoint(xfm, viewport.at);
  viewport.modified = true;

  viewport.modified = true;
}

void QOSPRayWindow::renderGL()
{
  // setup OpenGL state to match OSPRay view
  const osp::vec3f bgColor = osp::vec3f(1.f);
  glClearColor(bgColor.x, bgColor.y, bgColor.z, 1.f);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  float zNear = 0.1f;
  float zFar = 100000.f;
  gluPerspective(viewport.fovY, viewport.aspect, zNear, zFar);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(viewport.from.x, viewport.from.y, viewport.from.z,
            viewport.at.x, viewport.at.y, viewport.at.z,
            viewport.up.x, viewport.up.y, viewport.up.z);

  // emit signal to render all OpenGL components; the slots will execute in the order they were registered
  emit(renderGLComponents());
}

void QOSPRayWindow::writeFrameBufferToFile(const uint32 *pixelData)
{
  static uint32 frameNumber = 0;
  char filename[1024];
  sprintf(filename, "%s_%05u.ppm", writeFramesFilename.c_str(), frameNumber++);
  FILE *file = fopen(filename, "wb");  if (!file) { std::cerr << "unable to write to file '" << filename << "'" << std::endl;  return; }

  fprintf(file, "P6\n%i %i\n255\n", windowSize.x, windowSize.y);
  unsigned char out[3 * windowSize.x];
  for (int y=0 ; y < windowSize.y ; y++) {
    const unsigned char *in = (const unsigned char *) &pixelData[(windowSize.y - 1 - y) * windowSize.x];
    for (int x=0 ; x < windowSize.x ; x++) {
      out[3 * x + 0] = in[4 * x + 0];
      out[3 * x + 1] = in[4 * x + 1];
      out[3 * x + 2] = in[4 * x + 2];
    }
    fwrite(&out, 3 * windowSize.x, sizeof(char), file);
  }
  fprintf(file, "\n");
  fclose(file);
}
<|endoftext|>


<commit_before>#include <ChessboardSampling.hpp>
#include <calibvolume.hpp>
#include <rgbdsensor.hpp>
#include <DataTypes.hpp>
#include <CMDParser.hpp>
#include <sweepsampler.hpp>
#include <calibrator.hpp>

#include <fstream>
#include <iostream>
#include <iomanip>

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

  std::string pose_offset_filename = "../../../source/poseoffset";
  unsigned cv_width  = 128;
  unsigned cv_height = 128;
  unsigned cv_depth  = 256;
  float    cv_min_d  = 0.5;
  float    cv_max_d  = 4.5;

  // ./sweep_sampler ../../../data/23.cv ../../../data/23_sweep -t -0.157 -c -0.01

  const float tracking_offset_time_step = 0.001; // in seconds
  float tracking_offset_time_min = -0.2; // in seconds
  float tracking_offset_time_max = 0.0; // in seconds
  float color_offset_time = -0.01;

  unsigned idwneighbours = 20;
  std::string optimize_log("");
  bool using_nni = false;
  unsigned optimization_stride = 1;
  CMDParser p("calibvolumebasefilename checkerboardview_init checkerboardview_sweep");
  p.addOpt("p",1,"poseoffetfilename", "specify the filename where to store the poseoffset on disk, default: " + pose_offset_filename);
  p.addOpt("s",3,"size", "use this calibration volume size (width x height x depth), default: 128 128 256");
  p.addOpt("d",2,"depthrange", "use this depth range: 0.5 4.5");

  p.addOpt("t",2,"trackingoffsetrange", "min and max offset in seconds of the tracking system relative to depth frame of the sensor, e.g. -0.05 0.03, default: -0.2 0.0");
  p.addOpt("c",1,"coloroffset", "offset in seconds of the color frame relative to the depth frame of the sensor , e.g. -0.02, default: -0.01");

  p.addOpt("n",1,"numneighbours", "the number of neighbours that should be used for IDW inverse distance weighting, default: 20");

  p.addOpt("o",1,"optimizationstride", "perform optimization only for every n-th checkerboard location, default: 1");

  p.addOpt("l",1,"log", "log the optimization process to given filename, default: no log ");

  p.addOpt("i",-1,"nni", "do use natural neighbor interpolation if possible, default: false");

  p.init(argc,argv);

  if(p.isOptSet("p")){
    pose_offset_filename = p.getOptsString("p")[0];
    std::cout << "setting poseoffetfilename to " << pose_offset_filename << std::endl;
  }

  if(p.isOptSet("s")){
    cv_width = p.getOptsInt("s")[0];
    cv_height = p.getOptsInt("s")[1];
    cv_depth = p.getOptsInt("s")[2];
  }

  if(p.isOptSet("d")){
    cv_min_d = p.getOptsInt("d")[0];
    cv_max_d = p.getOptsInt("d")[1];
  }

  if(p.isOptSet("t")){
    tracking_offset_time_min = p.getOptsFloat("t")[0];
    tracking_offset_time_max = p.getOptsFloat("t")[1];
  }
  if(p.isOptSet("c")){
    color_offset_time = p.getOptsFloat("c")[0];
  }

  if(p.isOptSet("n")){
    idwneighbours = p.getOptsInt("n")[0];
  }

  if(p.isOptSet("o")){
    optimization_stride = p.getOptsInt("o")[0];
  }

  if(p.isOptSet("l")){
    optimize_log = p.getOptsString("l")[0];
  }

  if(p.isOptSet("i")){
    using_nni = true;
  }

  CalibVolume cv_init(cv_width, cv_height, cv_depth, cv_min_d, cv_max_d);

  RGBDConfig cfg;
  cfg.size_rgb = glm::uvec2(1280, 1080);
  cfg.size_d   = glm::uvec2(512, 424);

  cfg.principal_rgb = glm::vec2(701.972473, 532.143066);
  cfg.principal_d   = glm::vec2(257.009552, 209.077789);

  cfg.focal_rgb = glm::vec2(1030.829834, 1030.497070);
  cfg.focal_d   = glm::vec2(355.433716, 355.672363);

  cfg.eye_d_to_eye_rgb[0][0] = 0.999950;
  cfg.eye_d_to_eye_rgb[0][1] = -0.009198;
  cfg.eye_d_to_eye_rgb[0][2] = -0.003908;
  cfg.eye_d_to_eye_rgb[0][3] = 0.0;

  cfg.eye_d_to_eye_rgb[1][0] = 0.009169;
  cfg.eye_d_to_eye_rgb[1][1] = 0.999932;
  cfg.eye_d_to_eye_rgb[1][2] = -0.007234;
  cfg.eye_d_to_eye_rgb[1][3] = 0.0;

  cfg.eye_d_to_eye_rgb[2][0] = 0.003974;
  cfg.eye_d_to_eye_rgb[2][1] = 0.007198;
  cfg.eye_d_to_eye_rgb[2][2] = 0.999966;
  cfg.eye_d_to_eye_rgb[2][3] = 0.0;

  cfg.eye_d_to_eye_rgb[3][0] = -0.051237;
  cfg.eye_d_to_eye_rgb[3][1] = 0.000667;
  cfg.eye_d_to_eye_rgb[3][2] = 0.000195;
  cfg.eye_d_to_eye_rgb[3][3] = 1.0;

  RGBDSensor sensor(cfg);

  Checkerboard cb;
  cb.load_pose_offset(pose_offset_filename.c_str());
  // configure local 3D Points on chessboard here:
  for(unsigned y = 0; y < CB_HEIGHT; ++y){
    for(unsigned x = 0; x < CB_WIDTH; ++x){
      cb.points_local.push_back(glm::vec3(y * 0.075, x * 0.075,0.0));
    }
  }

  ChessboardSampling cbs(p.getArgs()[1].c_str());
  cbs.init();

  glm::mat4 eye_d_to_world = sensor.guess_eye_d_to_world_static(cbs, cb);
  std::cerr << "extrinsic of sensor is: " << eye_d_to_world << std::endl;
  std::cerr << "PLEASE note, the extrinsic guess can be improved by averaging" << std::endl;

  for(unsigned z = 0; z < cv_init.depth; ++z){
    for(unsigned y = 0; y < cv_init.height; ++y){
      for(unsigned x = 0; x < cv_init.width; ++x){

	const unsigned cv_index = (z * cv_init.width * cv_init.height) + (y * cv_init.width) + x;

	const float depth = (z + 0.5) * (cv_init.max_d - cv_init.min_d)/cv_init.depth + cv_init.min_d;
	const float xd = (x + 0.5) * sensor.config.size_d.x * 1.0/cv_init.width;
	const float yd = (y + 0.5) * sensor.config.size_d.y * 1.0/cv_init.height;

	glm::vec3 pos3D_local = sensor.calc_pos_d(xd, yd, depth);
	glm::vec2 pos2D_rgb   = sensor.calc_pos_rgb(pos3D_local);
	pos2D_rgb.x /= sensor.config.size_rgb.x;
	pos2D_rgb.y /= sensor.config.size_rgb.y;

	glm::vec4 pos3D_world = eye_d_to_world * glm::vec4(pos3D_local.x, pos3D_local.y, pos3D_local.z, 1.0);

	xyz pos3D;
	pos3D.x = pos3D_world.x;
	pos3D.y = pos3D_world.y;
	pos3D.z = pos3D_world.z;
	cv_init.cv_xyz[cv_index] = pos3D;

	uv posUV;
	posUV.u = pos2D_rgb.x;
	posUV.v = pos2D_rgb.y;
	cv_init.cv_uv[cv_index] = posUV;
      }
    }
  }

  const std::string basefilename = p.getArgs()[0];
  std::string filename_xyz(basefilename + "_xyz");
  std::string filename_uv(basefilename + "_uv");
  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());

  // 2. load recording from sweepfilename
  ChessboardSampling cs_sweep(p.getArgs()[2].c_str());
  cs_sweep.init();

  // 3. optimize tracking_offset_time
  std::ofstream* logfile;
  if(optimize_log != ""){
    logfile = new std::ofstream(optimize_log.c_str());
    *logfile << "tracking_offset_time;avg_quality;best_tracking_offset_time;best_avg_quality" << std::endl;
  }

  double best_avg_quality = 0.0f;
  float best_tracking_offset_time = (tracking_offset_time_max + tracking_offset_time_min) * 0.5f;
  for(float tracking_offset_time = tracking_offset_time_min;
      tracking_offset_time < tracking_offset_time_max;
      tracking_offset_time += tracking_offset_time_step){

    CalibVolume cv_sweep(filename_xyz.c_str(), filename_uv.c_str());

    cs_sweep.loadChessboards();

    SweepSampler ss(&cb, &cv_sweep, &cfg);
    const size_t numsamples = ss.extractSamples(&cs_sweep, tracking_offset_time, color_offset_time, optimization_stride);

    const std::vector<samplePoint>& sps = ss.getSamplePoints();

    Calibrator   c; // do not use nni during optimization
    c.applySamples(&cv_sweep, sps, cfg, idwneighbours);

    // evalute at valid chessboard location
    const double avg_quality = c.evalutePlanes(&cv_sweep, &cs_sweep, cfg, optimization_stride);

    if(avg_quality > best_avg_quality){
      best_avg_quality = avg_quality;
      best_tracking_offset_time = tracking_offset_time;
    }

    if(logfile != 0){
      *logfile << tracking_offset_time << ";" << std::setprecision(10) << avg_quality << ";" << best_tracking_offset_time << ";" << std::setprecision(10) << best_avg_quality << std::endl;
    }

    std::cout << "tracking_offset_time: " << tracking_offset_time << " (best: " << best_tracking_offset_time << ") -> avg_quality: " << avg_quality << " (best: " << best_avg_quality << ")" << std::endl;

  }

  if(logfile != 0){
    logfile->close();
  }
  std::cout << "best_tracking_offset_time: " << best_tracking_offset_time << std::endl;

  cs_sweep.loadChessboards();
  SweepSampler ss(&cb, &cv_init, &cfg);
  const size_t numsamples = ss.extractSamples(&cs_sweep, best_tracking_offset_time, color_offset_time);

  const std::vector<samplePoint>& sps = ss.getSamplePoints();
  Calibrator   c;
  c.using_nni = using_nni;
  c.applySamples(&cv_init, sps, cfg, idwneighbours);

  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());
  filename_xyz += "_sweep";
  filename_uv  += "_sweep";
  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());

  return 0;
}
<commit_msg>refactored brute force optimization code<commit_after>#include <ChessboardSampling.hpp>
#include <calibvolume.hpp>
#include <rgbdsensor.hpp>
#include <DataTypes.hpp>
#include <CMDParser.hpp>
#include <sweepsampler.hpp>
#include <calibrator.hpp>

#include <fstream>
#include <iostream>
#include <iomanip>

double sampleQuality(const std::string& filename_xyz, const std::string& filename_uv,
		     ChessboardSampling& cs_sweep,
		     const RGBDConfig& cfg,
		     const Checkerboard& cb,
		     const float tracking_offset_time,
		     const float color_offset_time,
		     const unsigned optimization_stride,
		     const unsigned idwneighbours){
    CalibVolume cv_sweep(filename_xyz.c_str(), filename_uv.c_str());
    cs_sweep.loadChessboards();
    SweepSampler ss(&cb, &cv_sweep, &cfg);
    ss.extractSamples(&cs_sweep, tracking_offset_time, color_offset_time, optimization_stride);
    const std::vector<samplePoint>& sps = ss.getSamplePoints();
    Calibrator   c; // do not use nni during optimization
    c.applySamples(&cv_sweep, sps, cfg, idwneighbours);
    // evalute at valid chessboard location
    return c.evalutePlanes(&cv_sweep, &cs_sweep, cfg, optimization_stride);
}

float optimizeBruteForce(const std::string& filename_xyz, const std::string& filename_uv,
			 ChessboardSampling& cs_sweep,
			 const RGBDConfig& cfg,
			 const Checkerboard& cb,
			 const float tracking_offset_time_min,
			 const float tracking_offset_time_max,
			 const float tracking_offset_time_step,
			 const float color_offset_time,
			 const unsigned optimization_stride,
			 const unsigned idwneighbours,
			 const std::string& optimize_log){

  std::ofstream* logfile;
  if(optimize_log != ""){
    logfile = new std::ofstream(optimize_log.c_str());
    *logfile << "tracking_offset_time;avg_quality;best_tracking_offset_time;best_avg_quality" << std::endl;
  }

  float best_tracking_offset_time = (tracking_offset_time_max + tracking_offset_time_min) * 0.5f;
  double best_avg_quality = 0.0f;
  for(float tracking_offset_time = tracking_offset_time_min;
      tracking_offset_time < tracking_offset_time_max;
      tracking_offset_time += tracking_offset_time_step){

#if 1
    const double avg_quality = sampleQuality(filename_xyz, filename_uv, cs_sweep, cfg, cb,
	      tracking_offset_time, color_offset_time, optimization_stride, idwneighbours);
#endif
#if 0
    CalibVolume cv_sweep(filename_xyz.c_str(), filename_uv.c_str());
    cs_sweep.loadChessboards();
    SweepSampler ss(&cb, &cv_sweep, &cfg);
    ss.extractSamples(&cs_sweep, tracking_offset_time, color_offset_time, optimization_stride);
    const std::vector<samplePoint>& sps = ss.getSamplePoints();
    Calibrator   c; // do not use nni during optimization
    c.applySamples(&cv_sweep, sps, cfg, idwneighbours);
    // evalute at valid chessboard location
    const double avg_quality = c.evalutePlanes(&cv_sweep, &cs_sweep, cfg, optimization_stride);
#endif

    if(avg_quality > best_avg_quality){
      best_avg_quality = avg_quality;
      best_tracking_offset_time = tracking_offset_time;
    }

    if(logfile != 0){
      *logfile << tracking_offset_time << ";" << std::setprecision(10) << avg_quality << ";" << best_tracking_offset_time << ";" << std::setprecision(10) << best_avg_quality << std::endl;
    }

    std::cout << "tracking_offset_time: " << tracking_offset_time << " (best: " << best_tracking_offset_time << ") -> avg_quality: " << avg_quality << " (best: " << best_avg_quality << ")" << std::endl;

  }
  if(logfile != 0){
    logfile->close();
  }
  return best_tracking_offset_time;
}

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

  std::string pose_offset_filename = "../../../source/poseoffset";
  unsigned cv_width  = 128;
  unsigned cv_height = 128;
  unsigned cv_depth  = 256;
  float    cv_min_d  = 0.5;
  float    cv_max_d  = 4.5;

  // ./sweep_calibrate ../../../data/23.cv ../../../data/23_init ../../../data/23_sweep -t -0.05 -0.0 -o 1 -l ../../../data/23.optimize_log.csv -i

  const float tracking_offset_time_step = 0.001; // in seconds
  float tracking_offset_time_min = -0.2; // in seconds
  float tracking_offset_time_max = 0.0; // in seconds
  float color_offset_time = -0.01;

  unsigned idwneighbours = 20;
  std::string optimize_log("");
  bool using_nni = false;
  unsigned optimization_stride = 1;
  CMDParser p("calibvolumebasefilename checkerboardview_init checkerboardview_sweep");
  p.addOpt("p",1,"poseoffetfilename", "specify the filename where to store the poseoffset on disk, default: " + pose_offset_filename);
  p.addOpt("s",3,"size", "use this calibration volume size (width x height x depth), default: 128 128 256");
  p.addOpt("d",2,"depthrange", "use this depth range: 0.5 4.5");

  p.addOpt("t",2,"trackingoffsetrange", "min and max offset in seconds of the tracking system relative to depth frame of the sensor, e.g. -0.05 0.03, default: -0.2 0.0");
  p.addOpt("c",1,"coloroffset", "offset in seconds of the color frame relative to the depth frame of the sensor , e.g. -0.02, default: -0.01");

  p.addOpt("n",1,"numneighbours", "the number of neighbours that should be used for IDW inverse distance weighting, default: 20");

  p.addOpt("o",1,"optimizationstride", "perform optimization only for every n-th checkerboard location, default: 1");

  p.addOpt("l",1,"log", "log the optimization process to given filename, default: no log ");

  p.addOpt("i",-1,"nni", "do use natural neighbor interpolation if possible, default: false");

  p.init(argc,argv);

  if(p.isOptSet("p")){
    pose_offset_filename = p.getOptsString("p")[0];
    std::cout << "setting poseoffetfilename to " << pose_offset_filename << std::endl;
  }

  if(p.isOptSet("s")){
    cv_width = p.getOptsInt("s")[0];
    cv_height = p.getOptsInt("s")[1];
    cv_depth = p.getOptsInt("s")[2];
  }

  if(p.isOptSet("d")){
    cv_min_d = p.getOptsInt("d")[0];
    cv_max_d = p.getOptsInt("d")[1];
  }

  if(p.isOptSet("t")){
    tracking_offset_time_min = p.getOptsFloat("t")[0];
    tracking_offset_time_max = p.getOptsFloat("t")[1];
  }
  if(p.isOptSet("c")){
    color_offset_time = p.getOptsFloat("c")[0];
  }

  if(p.isOptSet("n")){
    idwneighbours = p.getOptsInt("n")[0];
  }

  if(p.isOptSet("o")){
    optimization_stride = p.getOptsInt("o")[0];
  }

  if(p.isOptSet("l")){
    optimize_log = p.getOptsString("l")[0];
  }

  if(p.isOptSet("i")){
    using_nni = true;
  }

  CalibVolume cv_init(cv_width, cv_height, cv_depth, cv_min_d, cv_max_d);

  RGBDConfig cfg;
  cfg.size_rgb = glm::uvec2(1280, 1080);
  cfg.size_d   = glm::uvec2(512, 424);

  cfg.principal_rgb = glm::vec2(701.972473, 532.143066);
  cfg.principal_d   = glm::vec2(257.009552, 209.077789);

  cfg.focal_rgb = glm::vec2(1030.829834, 1030.497070);
  cfg.focal_d   = glm::vec2(355.433716, 355.672363);

  cfg.eye_d_to_eye_rgb[0][0] = 0.999950;
  cfg.eye_d_to_eye_rgb[0][1] = -0.009198;
  cfg.eye_d_to_eye_rgb[0][2] = -0.003908;
  cfg.eye_d_to_eye_rgb[0][3] = 0.0;

  cfg.eye_d_to_eye_rgb[1][0] = 0.009169;
  cfg.eye_d_to_eye_rgb[1][1] = 0.999932;
  cfg.eye_d_to_eye_rgb[1][2] = -0.007234;
  cfg.eye_d_to_eye_rgb[1][3] = 0.0;

  cfg.eye_d_to_eye_rgb[2][0] = 0.003974;
  cfg.eye_d_to_eye_rgb[2][1] = 0.007198;
  cfg.eye_d_to_eye_rgb[2][2] = 0.999966;
  cfg.eye_d_to_eye_rgb[2][3] = 0.0;

  cfg.eye_d_to_eye_rgb[3][0] = -0.051237;
  cfg.eye_d_to_eye_rgb[3][1] = 0.000667;
  cfg.eye_d_to_eye_rgb[3][2] = 0.000195;
  cfg.eye_d_to_eye_rgb[3][3] = 1.0;

  RGBDSensor sensor(cfg);

  Checkerboard cb;
  cb.load_pose_offset(pose_offset_filename.c_str());
  // configure local 3D Points on chessboard here:
  for(unsigned y = 0; y < CB_HEIGHT; ++y){
    for(unsigned x = 0; x < CB_WIDTH; ++x){
      cb.points_local.push_back(glm::vec3(y * 0.075, x * 0.075,0.0));
    }
  }

  ChessboardSampling cbs(p.getArgs()[1].c_str());
  cbs.init();

  glm::mat4 eye_d_to_world = sensor.guess_eye_d_to_world_static(cbs, cb);
  std::cerr << "extrinsic of sensor is: " << eye_d_to_world << std::endl;
  std::cerr << "PLEASE note, the extrinsic guess can be improved by averaging" << std::endl;

  for(unsigned z = 0; z < cv_init.depth; ++z){
    for(unsigned y = 0; y < cv_init.height; ++y){
      for(unsigned x = 0; x < cv_init.width; ++x){

	const unsigned cv_index = (z * cv_init.width * cv_init.height) + (y * cv_init.width) + x;

	const float depth = (z + 0.5) * (cv_init.max_d - cv_init.min_d)/cv_init.depth + cv_init.min_d;
	const float xd = (x + 0.5) * sensor.config.size_d.x * 1.0/cv_init.width;
	const float yd = (y + 0.5) * sensor.config.size_d.y * 1.0/cv_init.height;

	glm::vec3 pos3D_local = sensor.calc_pos_d(xd, yd, depth);
	glm::vec2 pos2D_rgb   = sensor.calc_pos_rgb(pos3D_local);
	pos2D_rgb.x /= sensor.config.size_rgb.x;
	pos2D_rgb.y /= sensor.config.size_rgb.y;

	glm::vec4 pos3D_world = eye_d_to_world * glm::vec4(pos3D_local.x, pos3D_local.y, pos3D_local.z, 1.0);

	xyz pos3D;
	pos3D.x = pos3D_world.x;
	pos3D.y = pos3D_world.y;
	pos3D.z = pos3D_world.z;
	cv_init.cv_xyz[cv_index] = pos3D;

	uv posUV;
	posUV.u = pos2D_rgb.x;
	posUV.v = pos2D_rgb.y;
	cv_init.cv_uv[cv_index] = posUV;
      }
    }
  }

  const std::string basefilename = p.getArgs()[0];
  std::string filename_xyz(basefilename + "_xyz");
  std::string filename_uv(basefilename + "_uv");
  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());

  // 2. load recording from sweepfilename
  ChessboardSampling cs_sweep(p.getArgs()[2].c_str());
  cs_sweep.init();

  float best_tracking_offset_time = 0.0f;
  // do it brutre force
  best_tracking_offset_time = optimizeBruteForce(filename_xyz, filename_uv,
						 cs_sweep,
						 cfg,
						 cb,
						 tracking_offset_time_min,
						 tracking_offset_time_max,
						 tracking_offset_time_step,
						 color_offset_time,
						 optimization_stride,
						 idwneighbours,
						 optimize_log);

  // do the calibration based on the best_tracking_offset_time
  std::cout << "best_tracking_offset_time: " << best_tracking_offset_time << std::endl;
  cs_sweep.loadChessboards();
  SweepSampler ss(&cb, &cv_init, &cfg);
  ss.extractSamples(&cs_sweep, best_tracking_offset_time, color_offset_time);

  const std::vector<samplePoint>& sps = ss.getSamplePoints();
  Calibrator   c;
  c.using_nni = using_nni;
  c.applySamples(&cv_init, sps, cfg, idwneighbours);

  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());
  filename_xyz += "_sweep";
  filename_uv  += "_sweep";
  cv_init.save(filename_xyz.c_str(), filename_uv.c_str());

  return 0;
}
<|endoftext|>