<commit_before>#include "Editor.hpp"

#include "Util/EditorSettings.hpp"
#undef CreateDirectory

#include <Engine/Util/Input.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/MainWindow.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Listener.hpp>
#include "ImGui/Theme.hpp"

#include <imgui.h>
#include <GLFW/glfw3.h>

Editor::Editor() {
    // Create Hymns directory.
    FileSystem::CreateDirectory((FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns").c_str());

    // Load theme.
    std::string theme = EditorSettings::GetInstance().GetString("Theme");
    if (FileSystem::FileExists((FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Themes" + FileSystem::DELIMITER + theme + ".json").c_str()))
        ImGui::LoadTheme(theme.c_str());
    else
        ImGui::LoadDefaultTheme();

    // Assign controls.
    Input()->AssignButton(InputHandler::PROFILE, InputHandler::KEYBOARD, GLFW_KEY_F2);
    Input()->AssignButton(InputHandler::PLAYTEST, InputHandler::KEYBOARD, GLFW_KEY_F5);
    Input()->AssignButton(InputHandler::CONTROL, InputHandler::KEYBOARD, GLFW_KEY_LEFT_CONTROL);
    Input()->AssignButton(InputHandler::NEW, InputHandler::KEYBOARD, GLFW_KEY_N);
    Input()->AssignButton(InputHandler::OPEN, InputHandler::KEYBOARD, GLFW_KEY_O);
    Input()->AssignButton(InputHandler::SAVE, InputHandler::KEYBOARD, GLFW_KEY_S);
    Input()->AssignButton(InputHandler::CAMERA, InputHandler::MOUSE, GLFW_MOUSE_BUTTON_MIDDLE);
    Input()->AssignButton(InputHandler::FORWARD, InputHandler::KEYBOARD, GLFW_KEY_W);
    Input()->AssignButton(InputHandler::BACKWARD, InputHandler::KEYBOARD, GLFW_KEY_S);
    Input()->AssignButton(InputHandler::LEFT, InputHandler::KEYBOARD, GLFW_KEY_A);
    Input()->AssignButton(InputHandler::RIGHT, InputHandler::KEYBOARD, GLFW_KEY_D);
    Input()->AssignButton(InputHandler::ZOOM, InputHandler::KEYBOARD, GLFW_KEY_Z);
    Input()->AssignButton(InputHandler::FOCUS, InputHandler::KEYBOARD, GLFW_KEY_F);

    // Create editor camera.
    cameraEntity = cameraWorld.CreateEntity("Editor Camera");
    cameraEntity->AddComponent<Component::Lens>();
    cameraEntity->position.z = 10.0f;

    // Create cursors.
    cursors[0] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
    cursors[1] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
    cursors[2] = glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR);
    cursors[3] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
    cursors[4] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);

    savePromptAnswered = false;
    close = false;

}

Editor::~Editor() {
    // Destroy cursors.
    for (int i = 0; i < 5; ++i) {
        glfwDestroyCursor(cursors[i]);
    }
}

void Editor::Show(float deltaTime) {

    if (close) {

        if (Hymn().GetPath() != "") {

            savePromtWindow.SetVisible(true);
            savePromtWindow.Show();

            switch (savePromtWindow.GetDecision()) {
            case 0:
                Save();
                savePromptAnswered = true;
                break;

            case 1:
                savePromptAnswered = true;
                break;

            default:
                break;
            }

        }
        else {

            savePromptAnswered = true;

        }

    }
    else {

        bool play = false;

        ImVec2 size(MainWindow::GetInstance()->GetSize().x, MainWindow::GetInstance()->GetSize().y);

        // Main menu bar.
        if (ImGui::BeginMainMenuBar()) {

            // File menu.
            if (ImGui::BeginMenu("File")) {
                if (ImGui::MenuItem("New Hymn", "CTRL+N"))
                    NewHymn();

                if (ImGui::MenuItem("Open Hymn", "CTRL+O"))
                    OpenHymn();

                if (Hymn().GetPath() != "") {

                    if (ImGui::MenuItem("Save Hymn", "CTRL+S"))
                        Save();

                }

                ImGui::Separator();

                if (ImGui::MenuItem("Settings"))
                    settingsWindow.SetVisible(true);

                ImGui::EndMenu();
            }

            // View menu.
            if (ImGui::BeginMenu("View")) {
                static bool soundSources = EditorSettings::GetInstance().GetBool("Sound Source Icons");
                ImGui::MenuItem("Sound Sources", "", &soundSources);
                EditorSettings::GetInstance().SetBool("Sound Source Icons", soundSources);

                static bool particleEmitters = EditorSettings::GetInstance().GetBool("Particle Emitter Icons");
                ImGui::MenuItem("Particle Emitters", "", &particleEmitters);
                EditorSettings::GetInstance().SetBool("Particle Emitter Icons", particleEmitters);

                static bool lightSources = EditorSettings::GetInstance().GetBool("Light Source Icons");
                ImGui::MenuItem("Light Sources", "", &lightSources);
                EditorSettings::GetInstance().SetBool("Light Source Icons", lightSources);

                static bool cameras = EditorSettings::GetInstance().GetBool("Camera Icons");
                ImGui::MenuItem("Cameras", "", &cameras);
                EditorSettings::GetInstance().SetBool("Camera Icons", cameras);

                ImGui::EndMenu();
            }

            if (Hymn().GetPath() != "") {
                // Play
                if (ImGui::BeginMenu("Play")) {
                    if (ImGui::MenuItem("Play", "F5"))
                        play = true;

                    ImGui::EndMenu();
                }

                // Hymn
                if (ImGui::BeginMenu("Hymn")) {
                    if (ImGui::MenuItem("Input"))
                        inputWindow.SetVisible(true);

                    if (ImGui::MenuItem("Filters"))
                        filtersWindow.SetVisible(true);

                    ImGui::EndMenu();
                }

                if (Input()->Triggered(InputHandler::ZOOM)) {
                    if (resourceList.GetScene().entityEditor.GetEntity() != nullptr) {
                        const glm::vec3 tempPos = resourceList.GetScene().entityEditor.GetEntity()->GetWorldPosition();
                        cameraEntity->position = tempPos + glm::vec3(0, 7, 7);
                        cameraEntity->rotation = glm::vec3(0, 45, 1);
                    }
                }

                // Editor Camera Coordinates
                ImGui::SameLine(size.x - 280); ImGui::Text("X: %f, Y: %f, Z: %f", cameraEntity->GetWorldPosition().x, cameraEntity->GetWorldPosition().y, cameraEntity->GetWorldPosition().z);
            }

            ImGui::EndMainMenuBar();
        }

        // Show hymn selection window.
        if (selectHymnWindow.IsVisible()) {
            ImGui::SetNextWindowPosCenter();
            selectHymnWindow.Show();
        }

        if (inputWindow.IsVisible())
            inputWindow.Show();

        // Show filters window.
        if (filtersWindow.IsVisible())
            filtersWindow.Show();

        // Show resource list.
        if (resourceList.IsVisible())
            resourceList.Show();

        // Show settings window.
        if (settingsWindow.IsVisible()) {
            settingsWindow.Show();
        }

        // Control the editor camera.
        if (Input()->Pressed(InputHandler::CAMERA)) {
            if (Input()->Triggered(InputHandler::CAMERA)) {
                lastX = Input()->GetCursorX();
                lastY = Input()->GetCursorY();
            }

            float sensitivity = 0.3f;
            cameraEntity->rotation.x += sensitivity * (Input()->GetCursorX() - lastX);
            cameraEntity->rotation.y += sensitivity * (Input()->GetCursorY() - lastY);

            lastX = Input()->GetCursorX();
            lastY = Input()->GetCursorY();

            glm::mat4 orientation = cameraEntity->GetCameraOrientation();
            glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
            glm::vec3 right(orientation[0][0], orientation[1][0], orientation[2][0]);

            //Move speed scaling.
            float speed = 10.0f * deltaTime * (glm::abs(cameraEntity->position.y) / 10.0f);
            float constantSpeed = 10.0f * deltaTime;

            if (cameraEntity->position.y > 10.0f || cameraEntity->position.y < -10.0f) {
                cameraEntity->position += speed * backward * static_cast<float>(Input()->Pressed(InputHandler::BACKWARD) - Input()->Pressed(InputHandler::FORWARD));
                cameraEntity->position += speed * right * static_cast<float>(Input()->Pressed(InputHandler::RIGHT) - Input()->Pressed(InputHandler::LEFT));
            } else {
                cameraEntity->position += constantSpeed * backward * static_cast<float>(Input()->Pressed(InputHandler::BACKWARD) - Input()->Pressed(InputHandler::FORWARD));
                cameraEntity->position += constantSpeed * right * static_cast<float>(Input()->Pressed(InputHandler::RIGHT) - Input()->Pressed(InputHandler::LEFT));
            }
        }

        // Move camera position and rotation to fixate on selected object.
        if (Input()->Triggered(InputHandler::FOCUS)) {

            // When mousepicking is added, change this vec3 to object pivot.
            glm::vec3 backward = glm::normalize(cameraEntity->position - glm::vec3(0, 0, 0));

            while (glm::length(glm::vec3(0, 0, 0) - cameraEntity->position) > 10) {
                cameraEntity->position -= backward;
            }

            while (glm::length(glm::vec3(0, 0, 0) - cameraEntity->position) < 10) {
                cameraEntity->position += backward;
            }
            // When mousepicking is added, change this vec3 to object pivot. NOTE Does this do the same as 'backward' ?
            glm::vec3 camDirection = glm::vec3(0, 0, 0) - cameraEntity->position;
            glm::normalize(camDirection);

            float yaw = std::atan2(camDirection.x, -camDirection.z);
            cameraEntity->rotation.x = glm::degrees(yaw);

            float xz = std::sqrt(camDirection.x * camDirection.x + camDirection.z * camDirection.z);
            float pitch = std::atan2(-camDirection.y, xz);
            cameraEntity->rotation.y = glm::degrees(pitch);

        }

        //Scroll zoom.
        if (Input()->GetScrollDown()) {
            if (!ImGui::IsMouseHoveringAnyWindow()) {
                glm::mat4 orientation = cameraEntity->GetCameraOrientation();
                glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
                float speed = 10.0f * deltaTime * (glm::length(cameraEntity->position) / 10.0f);
                cameraEntity->position += speed * backward * 10.0f;
            }
        }
        if (Input()->GetScrollUp()) {
            if (!ImGui::IsMouseHoveringAnyWindow()) {
                glm::mat4 orientation = cameraEntity->GetCameraOrientation();
                glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
                float speed = 10.0f * deltaTime * (glm::length(cameraEntity->position) / 10.0f);
                cameraEntity->position += speed * backward * -10.0f;
            }
        }

        if (Input()->Triggered(InputHandler::PLAYTEST) && Hymn().GetPath() != "")
            play = true;

        if (Input()->Triggered(InputHandler::NEW) && Input()->Pressed(InputHandler::CONTROL))
            NewHymn();

        if (Input()->Triggered(InputHandler::OPEN) && Input()->Pressed(InputHandler::CONTROL))
            OpenHymn();

        if (Hymn().GetPath() != "" && Input()->Triggered(InputHandler::SAVE) && Input()->Pressed(InputHandler::CONTROL))
            Save();

        if (play)
            Play();

    }

    // Set cursor.
    if (ImGui::GetMouseCursor() < 5) {
        glfwSetCursor(MainWindow::GetInstance()->GetGLFWWindow(), cursors[ImGui::GetMouseCursor()]);
    }

}

void Editor::Save() const {
    resourceList.SaveScene();
    Hymn().Save();
}

bool Editor::ReadyToClose() const {
    return savePromptAnswered;
}

void Editor::Close() {
    close = true;
}

bool Editor::IsVisible() const {
    return visible;
}

void Editor::SetVisible(bool visible) {
    this->visible = visible;
}

Entity* Editor::GetCamera() const {
    return cameraEntity;
}

void Editor::Play() {
    editorState = Hymn().ToJson();
    SetVisible(false);
    resourceList.HideEditors();
    resourceList.ResetScene();
    Managers().scriptManager->RegisterInput();
    Managers().scriptManager->BuildAllScripts();
}

void Editor::LoadEditorState() {
    Hymn().FromJson(editorState);
}

void Editor::NewHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::NewHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("New Hymn");
    selectHymnWindow.SetOpenButtonName("Create");
    selectHymnWindow.SetVisible(true);
}

void Editor::NewHymnClosed(const std::string& hymn) {
    // Create new hymn
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Clear();
        Hymn().world.CreateRoot();
        Hymn().SetPath(FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns" + FileSystem::DELIMITER + hymn);
        resourceList.SetVisible(true);

        // Default scene.
        Hymn().scenes.push_back("Scene #0");

        Entity* player = Hymn().world.GetRoot()->AddChild("Player");
        player->position.z = 10.f;
        player->AddComponent<Component::Lens>();
        player->AddComponent<Component::Listener>();

        Entity* sun = Hymn().world.GetRoot()->AddChild("Sun");
        sun->AddComponent<Component::DirectionalLight>();
    }

    selectHymnWindow.SetVisible(false);
}

void Editor::OpenHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::OpenHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("Open Hymn");
    selectHymnWindow.SetOpenButtonName("Open");
    selectHymnWindow.SetVisible(true);
}

void Editor::OpenHymnClosed(const std::string& hymn) {
    // Open hymn.
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Load(FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns" + FileSystem::DELIMITER + hymn);
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}<commit_msg>Added newline<commit_after>#include "Editor.hpp"

#include "Util/EditorSettings.hpp"
#undef CreateDirectory

#include <Engine/Util/Input.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/MainWindow.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Listener.hpp>
#include "ImGui/Theme.hpp"

#include <imgui.h>
#include <GLFW/glfw3.h>

Editor::Editor() {
    // Create Hymns directory.
    FileSystem::CreateDirectory((FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns").c_str());

    // Load theme.
    std::string theme = EditorSettings::GetInstance().GetString("Theme");
    if (FileSystem::FileExists((FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Themes" + FileSystem::DELIMITER + theme + ".json").c_str()))
        ImGui::LoadTheme(theme.c_str());
    else
        ImGui::LoadDefaultTheme();

    // Assign controls.
    Input()->AssignButton(InputHandler::PROFILE, InputHandler::KEYBOARD, GLFW_KEY_F2);
    Input()->AssignButton(InputHandler::PLAYTEST, InputHandler::KEYBOARD, GLFW_KEY_F5);
    Input()->AssignButton(InputHandler::CONTROL, InputHandler::KEYBOARD, GLFW_KEY_LEFT_CONTROL);
    Input()->AssignButton(InputHandler::NEW, InputHandler::KEYBOARD, GLFW_KEY_N);
    Input()->AssignButton(InputHandler::OPEN, InputHandler::KEYBOARD, GLFW_KEY_O);
    Input()->AssignButton(InputHandler::SAVE, InputHandler::KEYBOARD, GLFW_KEY_S);
    Input()->AssignButton(InputHandler::CAMERA, InputHandler::MOUSE, GLFW_MOUSE_BUTTON_MIDDLE);
    Input()->AssignButton(InputHandler::FORWARD, InputHandler::KEYBOARD, GLFW_KEY_W);
    Input()->AssignButton(InputHandler::BACKWARD, InputHandler::KEYBOARD, GLFW_KEY_S);
    Input()->AssignButton(InputHandler::LEFT, InputHandler::KEYBOARD, GLFW_KEY_A);
    Input()->AssignButton(InputHandler::RIGHT, InputHandler::KEYBOARD, GLFW_KEY_D);
    Input()->AssignButton(InputHandler::ZOOM, InputHandler::KEYBOARD, GLFW_KEY_Z);
    Input()->AssignButton(InputHandler::FOCUS, InputHandler::KEYBOARD, GLFW_KEY_F);

    // Create editor camera.
    cameraEntity = cameraWorld.CreateEntity("Editor Camera");
    cameraEntity->AddComponent<Component::Lens>();
    cameraEntity->position.z = 10.0f;

    // Create cursors.
    cursors[0] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
    cursors[1] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
    cursors[2] = glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR);
    cursors[3] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
    cursors[4] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);

    savePromptAnswered = false;
    close = false;

}

Editor::~Editor() {
    // Destroy cursors.
    for (int i = 0; i < 5; ++i) {
        glfwDestroyCursor(cursors[i]);
    }
}

void Editor::Show(float deltaTime) {

    if (close) {

        if (Hymn().GetPath() != "") {

            savePromtWindow.SetVisible(true);
            savePromtWindow.Show();

            switch (savePromtWindow.GetDecision()) {
            case 0:
                Save();
                savePromptAnswered = true;
                break;

            case 1:
                savePromptAnswered = true;
                break;

            default:
                break;
            }

        }
        else {

            savePromptAnswered = true;

        }

    }
    else {

        bool play = false;

        ImVec2 size(MainWindow::GetInstance()->GetSize().x, MainWindow::GetInstance()->GetSize().y);

        // Main menu bar.
        if (ImGui::BeginMainMenuBar()) {

            // File menu.
            if (ImGui::BeginMenu("File")) {
                if (ImGui::MenuItem("New Hymn", "CTRL+N"))
                    NewHymn();

                if (ImGui::MenuItem("Open Hymn", "CTRL+O"))
                    OpenHymn();

                if (Hymn().GetPath() != "") {

                    if (ImGui::MenuItem("Save Hymn", "CTRL+S"))
                        Save();

                }

                ImGui::Separator();

                if (ImGui::MenuItem("Settings"))
                    settingsWindow.SetVisible(true);

                ImGui::EndMenu();
            }

            // View menu.
            if (ImGui::BeginMenu("View")) {
                static bool soundSources = EditorSettings::GetInstance().GetBool("Sound Source Icons");
                ImGui::MenuItem("Sound Sources", "", &soundSources);
                EditorSettings::GetInstance().SetBool("Sound Source Icons", soundSources);

                static bool particleEmitters = EditorSettings::GetInstance().GetBool("Particle Emitter Icons");
                ImGui::MenuItem("Particle Emitters", "", &particleEmitters);
                EditorSettings::GetInstance().SetBool("Particle Emitter Icons", particleEmitters);

                static bool lightSources = EditorSettings::GetInstance().GetBool("Light Source Icons");
                ImGui::MenuItem("Light Sources", "", &lightSources);
                EditorSettings::GetInstance().SetBool("Light Source Icons", lightSources);

                static bool cameras = EditorSettings::GetInstance().GetBool("Camera Icons");
                ImGui::MenuItem("Cameras", "", &cameras);
                EditorSettings::GetInstance().SetBool("Camera Icons", cameras);

                ImGui::EndMenu();
            }

            if (Hymn().GetPath() != "") {
                // Play
                if (ImGui::BeginMenu("Play")) {
                    if (ImGui::MenuItem("Play", "F5"))
                        play = true;

                    ImGui::EndMenu();
                }

                // Hymn
                if (ImGui::BeginMenu("Hymn")) {
                    if (ImGui::MenuItem("Input"))
                        inputWindow.SetVisible(true);

                    if (ImGui::MenuItem("Filters"))
                        filtersWindow.SetVisible(true);

                    ImGui::EndMenu();
                }

                if (Input()->Triggered(InputHandler::ZOOM)) {
                    if (resourceList.GetScene().entityEditor.GetEntity() != nullptr) {
                        const glm::vec3 tempPos = resourceList.GetScene().entityEditor.GetEntity()->GetWorldPosition();
                        cameraEntity->position = tempPos + glm::vec3(0, 7, 7);
                        cameraEntity->rotation = glm::vec3(0, 45, 1);
                    }
                }

                // Editor Camera Coordinates
                ImGui::SameLine(size.x - 280); ImGui::Text("X: %f, Y: %f, Z: %f", cameraEntity->GetWorldPosition().x, cameraEntity->GetWorldPosition().y, cameraEntity->GetWorldPosition().z);
            }

            ImGui::EndMainMenuBar();
        }

        // Show hymn selection window.
        if (selectHymnWindow.IsVisible()) {
            ImGui::SetNextWindowPosCenter();
            selectHymnWindow.Show();
        }

        if (inputWindow.IsVisible())
            inputWindow.Show();

        // Show filters window.
        if (filtersWindow.IsVisible())
            filtersWindow.Show();

        // Show resource list.
        if (resourceList.IsVisible())
            resourceList.Show();

        // Show settings window.
        if (settingsWindow.IsVisible()) {
            settingsWindow.Show();
        }

        // Control the editor camera.
        if (Input()->Pressed(InputHandler::CAMERA)) {
            if (Input()->Triggered(InputHandler::CAMERA)) {
                lastX = Input()->GetCursorX();
                lastY = Input()->GetCursorY();
            }

            float sensitivity = 0.3f;
            cameraEntity->rotation.x += sensitivity * (Input()->GetCursorX() - lastX);
            cameraEntity->rotation.y += sensitivity * (Input()->GetCursorY() - lastY);

            lastX = Input()->GetCursorX();
            lastY = Input()->GetCursorY();

            glm::mat4 orientation = cameraEntity->GetCameraOrientation();
            glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
            glm::vec3 right(orientation[0][0], orientation[1][0], orientation[2][0]);

            //Move speed scaling.
            float speed = 10.0f * deltaTime * (glm::abs(cameraEntity->position.y) / 10.0f);
            float constantSpeed = 10.0f * deltaTime;

            if (cameraEntity->position.y > 10.0f || cameraEntity->position.y < -10.0f) {
                cameraEntity->position += speed * backward * static_cast<float>(Input()->Pressed(InputHandler::BACKWARD) - Input()->Pressed(InputHandler::FORWARD));
                cameraEntity->position += speed * right * static_cast<float>(Input()->Pressed(InputHandler::RIGHT) - Input()->Pressed(InputHandler::LEFT));
            } else {
                cameraEntity->position += constantSpeed * backward * static_cast<float>(Input()->Pressed(InputHandler::BACKWARD) - Input()->Pressed(InputHandler::FORWARD));
                cameraEntity->position += constantSpeed * right * static_cast<float>(Input()->Pressed(InputHandler::RIGHT) - Input()->Pressed(InputHandler::LEFT));
            }
        }

        // Move camera position and rotation to fixate on selected object.
        if (Input()->Triggered(InputHandler::FOCUS)) {

            // When mousepicking is added, change this vec3 to object pivot.
            glm::vec3 backward = glm::normalize(cameraEntity->position - glm::vec3(0, 0, 0));

            while (glm::length(glm::vec3(0, 0, 0) - cameraEntity->position) > 10) {
                cameraEntity->position -= backward;
            }

            while (glm::length(glm::vec3(0, 0, 0) - cameraEntity->position) < 10) {
                cameraEntity->position += backward;
            }
            // When mousepicking is added, change this vec3 to object pivot. NOTE Does this do the same as 'backward' ?
            glm::vec3 camDirection = glm::vec3(0, 0, 0) - cameraEntity->position;
            glm::normalize(camDirection);

            float yaw = std::atan2(camDirection.x, -camDirection.z);
            cameraEntity->rotation.x = glm::degrees(yaw);

            float xz = std::sqrt(camDirection.x * camDirection.x + camDirection.z * camDirection.z);
            float pitch = std::atan2(-camDirection.y, xz);
            cameraEntity->rotation.y = glm::degrees(pitch);

        }

        //Scroll zoom.
        if (Input()->GetScrollDown()) {
            if (!ImGui::IsMouseHoveringAnyWindow()) {
                glm::mat4 orientation = cameraEntity->GetCameraOrientation();
                glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
                float speed = 10.0f * deltaTime * (glm::length(cameraEntity->position) / 10.0f);
                cameraEntity->position += speed * backward * 10.0f;
            }
        }
        if (Input()->GetScrollUp()) {
            if (!ImGui::IsMouseHoveringAnyWindow()) {
                glm::mat4 orientation = cameraEntity->GetCameraOrientation();
                glm::vec3 backward(orientation[0][2], orientation[1][2], orientation[2][2]);
                float speed = 10.0f * deltaTime * (glm::length(cameraEntity->position) / 10.0f);
                cameraEntity->position += speed * backward * -10.0f;
            }
        }

        if (Input()->Triggered(InputHandler::PLAYTEST) && Hymn().GetPath() != "")
            play = true;

        if (Input()->Triggered(InputHandler::NEW) && Input()->Pressed(InputHandler::CONTROL))
            NewHymn();

        if (Input()->Triggered(InputHandler::OPEN) && Input()->Pressed(InputHandler::CONTROL))
            OpenHymn();

        if (Hymn().GetPath() != "" && Input()->Triggered(InputHandler::SAVE) && Input()->Pressed(InputHandler::CONTROL))
            Save();

        if (play)
            Play();

    }

    // Set cursor.
    if (ImGui::GetMouseCursor() < 5) {
        glfwSetCursor(MainWindow::GetInstance()->GetGLFWWindow(), cursors[ImGui::GetMouseCursor()]);
    }

}

void Editor::Save() const {
    resourceList.SaveScene();
    Hymn().Save();
}

bool Editor::ReadyToClose() const {
    return savePromptAnswered;
}

void Editor::Close() {
    close = true;
}

bool Editor::IsVisible() const {
    return visible;
}

void Editor::SetVisible(bool visible) {
    this->visible = visible;
}

Entity* Editor::GetCamera() const {
    return cameraEntity;
}

void Editor::Play() {
    editorState = Hymn().ToJson();
    SetVisible(false);
    resourceList.HideEditors();
    resourceList.ResetScene();
    Managers().scriptManager->RegisterInput();
    Managers().scriptManager->BuildAllScripts();
}

void Editor::LoadEditorState() {
    Hymn().FromJson(editorState);
}

void Editor::NewHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::NewHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("New Hymn");
    selectHymnWindow.SetOpenButtonName("Create");
    selectHymnWindow.SetVisible(true);
}

void Editor::NewHymnClosed(const std::string& hymn) {
    // Create new hymn
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Clear();
        Hymn().world.CreateRoot();
        Hymn().SetPath(FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns" + FileSystem::DELIMITER + hymn);
        resourceList.SetVisible(true);

        // Default scene.
        Hymn().scenes.push_back("Scene #0");

        Entity* player = Hymn().world.GetRoot()->AddChild("Player");
        player->position.z = 10.f;
        player->AddComponent<Component::Lens>();
        player->AddComponent<Component::Listener>();

        Entity* sun = Hymn().world.GetRoot()->AddChild("Sun");
        sun->AddComponent<Component::DirectionalLight>();
    }

    selectHymnWindow.SetVisible(false);
}

void Editor::OpenHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::OpenHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("Open Hymn");
    selectHymnWindow.SetOpenButtonName("Open");
    selectHymnWindow.SetVisible(true);
}

void Editor::OpenHymnClosed(const std::string& hymn) {
    // Open hymn.
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Load(FileSystem::DataPath("Hymn to Beauty") + FileSystem::DELIMITER + "Hymns" + FileSystem::DELIMITER + hymn);
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}
<|endoftext|>


<commit_before><commit_msg>fix indent<commit_after><|endoftext|>


<commit_before>#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/managed_allocator.hpp>
#include <agency/cuda/detail/terminate.hpp>
#include <agency/cuda/detail/workaround_unused_variable_warning.hpp>

namespace agency
{
namespace cuda
{
namespace detail
{

template<class T>
class allocator
{
  public:
    using value_type = T;

    __host__ __device__
    value_type* allocate(size_t n)
    {
      value_type* result = nullptr;

#ifndef __CUDA_ARCH__
      managed_allocator<T> alloc;
      result = alloc.allocate(n);
#else
      result = reinterpret_cast<T*>(malloc(sizeof(T)));

      if(result == nullptr)
      {
        terminate_with_message("agency::cuda::detail::allocator::allocate(): malloc failed");
      }
#endif

      return result;
    }

    __host__ __device__
    void deallocate(value_type* ptr, size_t n)
    {
#ifndef __CUDA_ARCH__
      managed_allocator<T> alloc;
      alloc.deallocate(ptr, n);
#else
      agency::cuda::detail::workaround_unused_variable_warning(n);

      free(ptr);
#endif
    }

    template<class U, class... Args>
    __host__ __device__
    void construct(U* ptr, Args&&... args)
    {
#ifndef __CUDA_ARCH__
      managed_allocator<U> alloc;
      alloc.template construct<U>(ptr, std::forward<Args>(args)...);
#else
      new(ptr) U(std::forward<Args>(args)...);
#endif
    }
}; // end allocator

} // end detail
} // end cuda
} // end agency

<commit_msg>Generalize the type of allocator used to allocate on the host in cuda::detail::allocator<commit_after>#pragma once

#include <agency/detail/config.hpp>
#include <agency/cuda/detail/managed_allocator.hpp>
#include <agency/cuda/detail/terminate.hpp>
#include <agency/cuda/detail/workaround_unused_variable_warning.hpp>

namespace agency
{
namespace cuda
{
namespace detail
{

template<class T, class Alloc = managed_allocator<T>>
class allocator
{
  private:
    using host_allocator = typename std::allocator_traits<Alloc>::template rebind_alloc<T>;

  public:
    using value_type = T;

    __host__ __device__
    value_type* allocate(size_t n)
    {
      value_type* result = nullptr;

#ifndef __CUDA_ARCH__
      host_allocator alloc;
      result = alloc.allocate(n);
#else
      result = reinterpret_cast<T*>(malloc(sizeof(T)));

      if(result == nullptr)
      {
        terminate_with_message("agency::cuda::detail::allocator::allocate(): malloc failed");
      }
#endif

      return result;
    }

    __host__ __device__
    void deallocate(value_type* ptr, size_t n)
    {
#ifndef __CUDA_ARCH__
      host_allocator alloc;
      alloc.deallocate(ptr, n);
#else
      agency::cuda::detail::workaround_unused_variable_warning(n);

      free(ptr);
#endif
    }

    template<class U, class... Args>
    __host__ __device__
    void construct(U* ptr, Args&&... args)
    {
#ifndef __CUDA_ARCH__
      host_allocator alloc;
      alloc.template construct<U>(ptr, std::forward<Args>(args)...);
#else
      new(ptr) U(std::forward<Args>(args)...);
#endif
    }
}; // end allocator

} // end detail
} // end cuda
} // end agency

<|endoftext|>


<commit_before>
// Boat.cpp

// Implements the cBoat class representing a boat in the world

#include "Globals.h"
#include "Boat.h"
#include "../World.h"
#include "../ClientHandle.h"
#include "Player.h"

cBoat::cBoat(double a_X, double a_Y, double a_Z) :
	super(etBoat, a_X, a_Y, a_Z, 0.98, 0.7)
{
	SetMass(20.f);
	SetMaxHealth(6);
	SetHealth(6);
}

void cBoat::SpawnOn(cClientHandle & a_ClientHandle)
{
	a_ClientHandle.SendSpawnVehicle(*this, 1);
}

void cBoat::DoTakeDamage(TakeDamageInfo & TDI)
{
	super::DoTakeDamage(TDI);

	if (GetHealth() == 0)
	{
		if (TDI.Attacker != NULL)
		{
			if (TDI.Attacker->IsPlayer())
			{
				cItems Pickups;
				Pickups.Add(cItem(E_ITEM_BOAT));
				m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 0, 0, 0, true);
			}
		}
		Destroy(true);
	}
}

void cBoat::OnRightClicked(cPlayer & a_Player)
{
	if (m_Attachee != NULL)
	{
		if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())
		{
			// This player is already sitting in, they want out.
			a_Player.Detach();
			return;
		}

		if (m_Attachee->IsPlayer())
		{
			// Another player is already sitting in here, cannot attach
			return;
		}

		// Detach whatever is sitting in this boat now:
		m_Attachee->Detach();
	}

	// Attach the player to this boat
	a_Player.AttachTo(this);
}

void cBoat::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);
	BroadcastMovementUpdate();
	SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed.
	if (IsBlockWater(m_World->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ())))
	{
		SetSpeedY(1);
	}
}

void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
{
	if (GetSpeed().Length() > 7)
	{
		return;
	}

	Vector3d ToAddSpeed(m_Attachee->GetLookVector() * (a_Sideways * 1.5));
	ToAddSpeed.y = 0;

	AddSpeed(ToAddSpeed);
}

	<commit_msg>Fixed a boat ASSERT<commit_after>
// Boat.cpp

// Implements the cBoat class representing a boat in the world

#include "Globals.h"
#include "Boat.h"
#include "../World.h"
#include "../ClientHandle.h"
#include "Player.h"

cBoat::cBoat(double a_X, double a_Y, double a_Z) :
	super(etBoat, a_X, a_Y, a_Z, 0.98, 0.7)
{
	SetMass(20.f);
	SetMaxHealth(6);
	SetHealth(6);
}

void cBoat::SpawnOn(cClientHandle & a_ClientHandle)
{
	a_ClientHandle.SendSpawnVehicle(*this, 1);
}

void cBoat::DoTakeDamage(TakeDamageInfo & TDI)
{
	super::DoTakeDamage(TDI);

	if (GetHealth() == 0)
	{
		if (TDI.Attacker != NULL)
		{
			if (TDI.Attacker->IsPlayer())
			{
				cItems Pickups;
				Pickups.Add(cItem(E_ITEM_BOAT));
				m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 0, 0, 0, true);
			}
		}
		Destroy(true);
	}
}

void cBoat::OnRightClicked(cPlayer & a_Player)
{
	if (m_Attachee != NULL)
	{
		if (m_Attachee->GetUniqueID() == a_Player.GetUniqueID())
		{
			// This player is already sitting in, they want out.
			a_Player.Detach();
			return;
		}

		if (m_Attachee->IsPlayer())
		{
			// Another player is already sitting in here, cannot attach
			return;
		}

		// Detach whatever is sitting in this boat now:
		m_Attachee->Detach();
	}

	// Attach the player to this boat
	a_Player.AttachTo(this);
}

void cBoat::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);
	BroadcastMovementUpdate();
	SetSpeed(GetSpeed() * 0.97); // Slowly decrease the speed

	if ((POSY_TOINT < 0) || (POSY_TOINT > cChunkDef::Height))
	{
		return;
	}

	if (IsBlockWater(m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT)))
	{
		SetSpeedY(1);
	}
}

void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways)
{
	if (GetSpeed().Length() > 7)
	{
		return;
	}

	Vector3d ToAddSpeed(m_Attachee->GetLookVector() * (a_Sideways * 1.5));
	ToAddSpeed.y = 0;

	AddSpeed(ToAddSpeed);
}

	<|endoftext|>


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

/**
 * @file MainWnd.cpp
 * @date 2015. 9. 17.
 * @author dlarudgus20
 * @copyright The BSD (2-Clause) License
 */

#include "pch.h"
#include "MainWnd.h"

const int MAINWND_WIDTH = 800;
const int MAINWND_HEIGHT = 600;

std::unique_ptr<MainWnd> MainWnd::createInstance()
{
	return std::unique_ptr<MainWnd>(new MainWnd());
}

MainWnd::MainWnd()
	: m_wnd(nullptr)
{
	// TODO Auto-generated constructor stub
}

MainWnd::~MainWnd()
{
	// TODO Auto-generated destructor stub
}

bool MainWnd::create()
{
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
	m_wnd = glfwCreateWindow(MAINWND_WIDTH, MAINWND_HEIGHT, "pfps", nullptr, nullptr);
	if (m_wnd != nullptr)
	{
		glfwMakeContextCurrent(m_wnd);
		glfwSetWindowUserPointer(m_wnd, this);

		initCallback();
		return true;
	}
	else
	{
		return false;
	}
}

auto timeStr = [] (double time) {
	int s = static_cast<int>(time);
	char buf[11];
	int hour = s / 3600;
	int minutes = (s % 3600) / 60;
	int seconds = s % 60;
	snprintf(buf, 11, "[%02d:%02d:%02d]", hour, minutes, seconds);
	return std::string(buf);
};

void MainWnd::loop()
{
	static double startTime = glfwGetTime();
	static double frameTime = startTime, prevFrameTime;
	static double fpsResetTime = startTime + 1.0f;
	static int fps = 0;

	while (!glfwWindowShouldClose(m_wnd))
	{
		glfwPollEvents();
		render();
		fps++;
		idle();

		prevFrameTime = frameTime;
		frameTime = glfwGetTime();
		m_deltaTime = frameTime - prevFrameTime;

		if (fpsResetTime <= frameTime)
		{
			m_fps = fps;
			fps = 0;
			fpsResetTime += 1.0;
			std::cout << timeStr(frameTime) << " fps: " << m_fps << std::endl;
		}
	}
}

void MainWnd::loopManualFPS()
{
	const double expectedDelta = 1.0 / 60.0;

	static double startTime = glfwGetTime();

	static double frameTime = startTime, prevFrameTime;
	static double remain = 0.0f;
	static int fps = 0;

	static double fpsResetTime = startTime + 1.0;

	while (!glfwWindowShouldClose(m_wnd))
	{
		glfwPollEvents();

		if (remain <= 0.0f)
		{
			render();
			fps++;
		}

		idle();

		prevFrameTime = frameTime;
		frameTime = glfwGetTime();
		m_deltaTime = frameTime - prevFrameTime;

		if (fpsResetTime <= frameTime)
		{
			m_fps = fps;
			fps = 0;
			fpsResetTime += 1.0;
			std::cout << timeStr(frameTime) << " fps: " << m_fps << std::endl;
		}

		if (remain <= 0.0f)
		{
			remain += expectedDelta - m_deltaTime;
		}
		else
		{
			remain -= m_deltaTime;
		}
	}
}

void MainWnd::initCallback()
{
#define THIZ static_cast<MainWnd *>(glfwGetWindowUserPointer(wnd))
	glfwSetFramebufferSizeCallback(m_wnd, [] (GLFWwindow *wnd, int width, int height) {
		THIZ->onFrameBufferSize(width, height);
	});
	glfwSetWindowCloseCallback(m_wnd, [](GLFWwindow *wnd) {
		THIZ->onWindowClose();
	});
	glfwSetCursorPosCallback(m_wnd, [](GLFWwindow *wnd, double xpos, double ypos) {
		THIZ->onMouseCursorPos(xpos, ypos);
	});
#undef THIZ
}

bool MainWnd::initialize()
{
	glfwSetInputMode(m_wnd, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

	int width, height;
	glfwGetFramebufferSize(m_wnd, &width, &height);

	glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
	calcProjection(width, height);

	glEnable(GL_DEPTH_TEST);

	try
	{
		m_shader.compile("src/vertex.glsl", "src/fragment.glsl");
		m_shaderNolight.compile("src/vertex.glsl", "src/frag_nolight.glsl");
	}
	catch (Shader::CompileError &e)
	{
		std::cerr << "[Shader::CompileError] " << e.what() << std::endl;
		return false;
	}

	m_dirLight.setDirection({ -2.0f, -1.0f, -1.2f });
	m_dirLight.setAmbient({ 0.1f, 0.1f, 0.1f });
	m_dirLight.setDiffuse({ 0.3f, 0.3f, 0.3f });
	m_dirLight.setSpecular({ 0.3f, 0.3f, 0.3f });

	glm::vec3 ptLightPositions[] = {
		{ 0.7f,  0.2f,  2.0f },
		{ -4.0f,  2.0f, -12.0f },
		{ 0.0f,  0.0f, -3.0f },
		{ 1.0f, -1.5f, 0.4f }
	};
	for (int i = 0; i < Shader::POINTLIGHT_COUNT; ++i)
	{
		m_ptLights[i].setIndex(i);
		m_ptLights[i].setPosition(ptLightPositions[i]);
		m_ptLights[i].setAmbient({ 0.1f, 0.1f, 0.1f });
		m_ptLights[i].setDiffuse({ 1.0f, 1.0f, 1.0f });
		m_ptLights[i].setSpecular({ 1.0f, 1.0f, 1.0f });
		m_ptLights[i].setAttenuation(1.0f, 0.14f, 0.07f);
	}

	m_spLight.setPosition({ 2.3f, -3.3f, -4.0f });
	m_spLight.setDirection({ -2.3f, 3.3f, 4.0f });
	m_spLight.setAmbient({ 0.1f, 0.1f, 0.1f });
	m_spLight.setDiffuse({ 1.0f, 1.0f, 1.0f });
	m_spLight.setSpecular({ 1.0f, 1.0f, 1.0f });
	m_spLight.setCutOff(std::cos(glm::radians(12.5f)), std::cos(glm::radians(17.5f)));

	m_container.initialize();

	return true;
}

void MainWnd::render()
{
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glm::mat4 vmMatrix = m_camera.getMatrix();
	glm::mat3 normalMatrix;

	auto calcNormalMat = [&] {
		normalMatrix = glm::mat3(glm::transpose(glm::inverse(vmMatrix)));
	};
	calcNormalMat();

	glm::vec3 cubePositions[] = {
		{ 0.0f,  0.0f,  0.0f },
		{ 2.0f,  5.0f, -15.0f },
		{ -1.5f, -2.2f, -2.5f },
		{ -3.8f, -2.0f, -12.3f },
		{ 2.4f, -0.4f, -3.5f },
		{ -1.7f,  3.0f, -7.5f },
		{ 1.3f, -2.0f, -2.5f },
		{ 1.5f,  2.0f, -2.5f },
		{ 1.5f,  0.2f, -1.5f },
		{ -1.3f,  1.0f, -1.5f }
	};

	m_shader.use();
	m_shader.setUniformMatrix4f("projMatrix", m_projection);
	m_dirLight.apply(m_camera.getMatrix());
	for (const auto &ptLight : m_ptLights)
		ptLight.apply(m_camera.getMatrix());
	m_spLight.apply(m_camera.getMatrix());

	for (size_t i = 0; i < sizeof(cubePositions) / sizeof(cubePositions[0]); ++i)
	{
		float angle = glm::radians(20.f * i);

		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, cubePositions[i]);
		vmMatrix = glm::rotate(vmMatrix, angle, glm::vec3(1.0f, 0.3f, 0.5f));
		calcNormalMat();

		m_shader.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_shader.setUniformMatrix3f("NormalMatrix", normalMatrix);
		m_container.draw();

		vmMatrix = prevMat;
	}

	m_shaderNolight.use();
	m_shader.setUniformMatrix4f("projMatrix", m_projection);

	// point light
	for (int i = 0; i < Shader::POINTLIGHT_COUNT; ++i)
	{
		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, m_ptLights[i].getPosition());
		vmMatrix = glm::scale(vmMatrix, glm::vec3(0.2f));

		m_shaderNolight.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_container.draw(false);

		vmMatrix = prevMat;
	}
	// spot light
	{
		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, m_spLight.getPosition());
		vmMatrix = glm::scale(vmMatrix, glm::vec3(0.2f));

		m_shaderNolight.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_container.draw(false);

		vmMatrix = prevMat;
	}

	glfwSwapBuffers(m_wnd);
}

void MainWnd::idle()
{
	const float unit = 2.5f;

	int front = 0, right = 0;
	front += glfwGetKey(m_wnd, GLFW_KEY_W) == GLFW_PRESS ? 1 : 0;
	front += glfwGetKey(m_wnd, GLFW_KEY_S) == GLFW_PRESS ? -1 : 0;
	right += glfwGetKey(m_wnd, GLFW_KEY_D) == GLFW_PRESS ? 1 : 0;
	right += glfwGetKey(m_wnd, GLFW_KEY_A) == GLFW_PRESS ? -1 : 0;

	m_camera.move(front, right, unit * m_deltaTime);
}

void MainWnd::calcProjection(int width, int height)
{
	float aspect;

	// 최소화 상태일땐 width == height == 0임.
	if (width == 0 || height == 0)
		aspect = 1.0f;
	else
		aspect = (float)width / height;

	m_projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f);
}

void MainWnd::onMouseCursorPos(double xpos, double ypos)
{
	if (m_isFirstMouse)
	{
		m_prevMouseX = (float)xpos;
		m_prevMouseY = (float)ypos;
		m_isFirstMouse = false;
	}
	else
	{
		int width, height;
		glfwGetFramebufferSize(m_wnd, &width, &height);
		if (!(width == 0 || height == 0))
		{
			const float maxPitch = glm::radians(75.0f);

			const float unit = glm::radians(60.0f);

			float dx = (float)xpos - m_prevMouseX;
			float dy = -((float)ypos - m_prevMouseY);

			float pitch = m_camera.getPitch() + (dy / height) * unit;
			float yaw = m_camera.getYaw() + (dx / width) * unit;

			if (pitch > maxPitch)
				pitch = maxPitch;
			else if (pitch < -maxPitch)
				pitch = -maxPitch;

			m_camera.setPitchYaw(pitch, yaw);

			m_prevMouseX = (float)xpos;
			m_prevMouseY = (float)ypos;
		}
	}
}

void MainWnd::onFrameBufferSize(int width, int height)
{
	// 최소화 상태일땐 width == height == 0임.
	if (!(width == 0 || height == 0))
	{
		glViewport(0, 0, width, height);
		calcProjection(width, height);
	}
}

void MainWnd::onWindowClose()
{
	// TODO: onWindowClose
}
<commit_msg>some changes..<commit_after>// Copyright (c) 2014, 임경현
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * @file MainWnd.cpp
 * @date 2015. 9. 17.
 * @author dlarudgus20
 * @copyright The BSD (2-Clause) License
 */

#include "pch.h"
#include "MainWnd.h"

const int MAINWND_WIDTH = 800;
const int MAINWND_HEIGHT = 600;

std::unique_ptr<MainWnd> MainWnd::createInstance()
{
	return std::unique_ptr<MainWnd>(new MainWnd());
}

MainWnd::MainWnd()
	: m_wnd(nullptr)
{
	// TODO Auto-generated constructor stub
}

MainWnd::~MainWnd()
{
	// TODO Auto-generated destructor stub
}

bool MainWnd::create()
{
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
	m_wnd = glfwCreateWindow(MAINWND_WIDTH, MAINWND_HEIGHT, "pfps", nullptr, nullptr);
	if (m_wnd != nullptr)
	{
		glfwMakeContextCurrent(m_wnd);
		glfwSetWindowUserPointer(m_wnd, this);

		initCallback();
		return true;
	}
	else
	{
		return false;
	}
}

auto timeStr = [] (double time) {
	int s = static_cast<int>(time);
	char buf[11];
	int hour = s / 3600;
	int minutes = (s % 3600) / 60;
	int seconds = s % 60;
	snprintf(buf, 11, "[%02d:%02d:%02d]", hour, minutes, seconds);
	return std::string(buf);
};

void MainWnd::loop()
{
	static double startTime = glfwGetTime();
	static double frameTime = startTime, prevFrameTime;
	static double fpsResetTime = startTime + 1.0f;
	static int fps = 0;

	while (!glfwWindowShouldClose(m_wnd))
	{
		glfwPollEvents();
		render();
		fps++;
		idle();

		prevFrameTime = frameTime;
		frameTime = glfwGetTime();
		m_deltaTime = frameTime - prevFrameTime;

		if (fpsResetTime <= frameTime)
		{
			m_fps = fps;
			fps = 0;
			fpsResetTime += 1.0;
			std::cout << timeStr(frameTime) << " fps: " << m_fps << std::endl;
		}
	}
}

void MainWnd::loopManualFPS()
{
	const double expectedDelta = 1.0 / 60.0;

	static double startTime = glfwGetTime();

	static double frameTime = startTime, prevFrameTime;
	static double remain = 0.0f;
	static int fps = 0;

	static double fpsResetTime = startTime + 1.0;

	while (!glfwWindowShouldClose(m_wnd))
	{
		glfwPollEvents();

		if (remain <= 0.0f)
		{
			render();
			fps++;
		}

		idle();

		prevFrameTime = frameTime;
		frameTime = glfwGetTime();
		m_deltaTime = frameTime - prevFrameTime;

		if (fpsResetTime <= frameTime)
		{
			m_fps = fps;
			fps = 0;
			fpsResetTime += 1.0;
			std::cout << timeStr(frameTime) << " fps: " << m_fps << std::endl;
		}

		if (remain <= 0.0f)
		{
			remain += expectedDelta - m_deltaTime;
		}
		else
		{
			remain -= m_deltaTime;
		}
	}
}

void MainWnd::initCallback()
{
#define THIZ static_cast<MainWnd *>(glfwGetWindowUserPointer(wnd))
	glfwSetFramebufferSizeCallback(m_wnd, [] (GLFWwindow *wnd, int width, int height) {
		THIZ->onFrameBufferSize(width, height);
	});
	glfwSetWindowCloseCallback(m_wnd, [](GLFWwindow *wnd) {
		THIZ->onWindowClose();
	});
	glfwSetCursorPosCallback(m_wnd, [](GLFWwindow *wnd, double xpos, double ypos) {
		THIZ->onMouseCursorPos(xpos, ypos);
	});
#undef THIZ
}

bool MainWnd::initialize()
{
	glfwSetInputMode(m_wnd, GLFW_CURSOR, GLFW_CURSOR_DISABLED);

	int width, height;
	glfwGetFramebufferSize(m_wnd, &width, &height);

	glViewport(0, 0, static_cast<GLsizei>(width), static_cast<GLsizei>(height));
	calcProjection(width, height);

	glEnable(GL_DEPTH_TEST);

	try
	{
		m_shader.compile("src/vertex.glsl", "src/fragment.glsl");
		m_shaderNolight.compile("src/vertex.glsl", "src/frag_nolight.glsl");
	}
	catch (Shader::CompileError &e)
	{
		std::cerr << "[Shader::CompileError] " << e.what() << std::endl;
		return false;
	}

	//m_dirLight.setDirection({ -2.0f, -1.0f, -1.2f });
	//m_dirLight.setAmbient({ 0.1f, 0.1f, 0.1f });
	//m_dirLight.setDiffuse({ 0.3f, 0.3f, 0.3f });
	//m_dirLight.setSpecular({ 0.3f, 0.3f, 0.3f });

	glm::vec3 ptLightPositions[] = {
		{ 2.3f, -3.3f, -4.0f },
		{ 0.7f,  0.2f,  2.0f },
		{ -4.0f,  2.0f, -12.0f },
		{ 0.0f,  0.0f, -3.0f },
	};
	for (int i = 0; i < Shader::POINTLIGHT_COUNT; ++i)
	{
		m_ptLights[i].setIndex(i);
		m_ptLights[i].setPosition(ptLightPositions[i]);
		m_ptLights[i].setAmbient({ 0.1f, 0.1f, 0.1f });
		m_ptLights[i].setDiffuse({ 1.0f, 1.0f, 1.0f });
		m_ptLights[i].setSpecular({ 1.0f, 1.0f, 1.0f });
		m_ptLights[i].setAttenuation(1.0f, 0.14f * 0.4, 0.07f * 0.4);
	}

	//m_spLight.setPosition({ 2.3f, -3.3f, -4.0f });
	//m_spLight.setDirection({ -2.3f, 3.3f, 4.0f });
	//m_spLight.setAmbient({ 0.1f, 0.1f, 0.1f });
	//m_spLight.setDiffuse({ 1.0f, 1.0f, 1.0f });
	//m_spLight.setSpecular({ 1.0f, 1.0f, 1.0f });
	//m_spLight.setCutOff(std::cos(glm::radians(12.5f)), std::cos(glm::radians(17.5f)));

	m_container.initialize();

	return true;
}

void MainWnd::render()
{
	glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glm::mat4 vmMatrix = m_camera.getMatrix();
	glm::mat3 normalMatrix;

	auto calcNormalMat = [&] {
		normalMatrix = glm::mat3(glm::transpose(glm::inverse(vmMatrix)));
	};
	calcNormalMat();

	glm::vec3 cubePositions[] = {
		{ 0.0f,  0.0f,  0.0f },
		{ 2.0f,  5.0f, -15.0f },
		{ -1.5f, -2.2f, -2.5f },
		{ -3.8f, -2.0f, -12.3f },
		{ 2.4f, -0.4f, -3.5f },
		{ -1.7f,  3.0f, -7.5f },
		{ 1.3f, -2.0f, -2.5f },
		{ 1.5f,  2.0f, -2.5f },
		{ 1.5f,  0.2f, -1.5f },
		{ -1.3f,  1.0f, -1.5f }
	};

	m_shader.use();
	m_shader.setUniformMatrix4f("projMatrix", m_projection);
	m_dirLight.apply(m_camera.getMatrix());
	for (const auto &ptLight : m_ptLights)
		ptLight.apply(m_camera.getMatrix());
	m_spLight.apply(m_camera.getMatrix());

	for (size_t i = 0; i < sizeof(cubePositions) / sizeof(cubePositions[0]); ++i)
	{
		float angle = glm::radians(20.f * i);

		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, cubePositions[i]);
		vmMatrix = glm::rotate(vmMatrix, angle, glm::vec3(1.0f, 0.3f, 0.5f));
		calcNormalMat();

		m_shader.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_shader.setUniformMatrix3f("NormalMatrix", normalMatrix);
		m_container.draw();

		vmMatrix = prevMat;
	}

	{
		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, { 0.0f, -9.0f, 0.0f });
		vmMatrix = glm::scale(vmMatrix, { 10.0f, 10.0f, 10.0f });
		calcNormalMat();

		m_shader.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_shader.setUniformMatrix3f("NormalMatrix", normalMatrix);
		m_container.draw();

		vmMatrix = prevMat;
	}

	m_shaderNolight.use();
	m_shader.setUniformMatrix4f("projMatrix", m_projection);

	// point light
	for (int i = 0; i < Shader::POINTLIGHT_COUNT; ++i)
	{
		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, m_ptLights[i].getPosition());
		vmMatrix = glm::scale(vmMatrix, glm::vec3(0.2f));

		m_shaderNolight.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_container.draw(false);

		vmMatrix = prevMat;
	}
	// spot light
	{
		glm::mat4 prevMat = vmMatrix;
		vmMatrix = glm::translate(vmMatrix, m_spLight.getPosition());
		vmMatrix = glm::scale(vmMatrix, glm::vec3(0.2f));

		m_shaderNolight.setUniformMatrix4f("vmMatrix", vmMatrix);
		m_container.draw(false);

		vmMatrix = prevMat;
	}

	glfwSwapBuffers(m_wnd);
}

void MainWnd::idle()
{
	const float unit = 2.5f;

	int front = 0, right = 0;
	front += glfwGetKey(m_wnd, GLFW_KEY_W) == GLFW_PRESS ? 1 : 0;
	front += glfwGetKey(m_wnd, GLFW_KEY_S) == GLFW_PRESS ? -1 : 0;
	right += glfwGetKey(m_wnd, GLFW_KEY_D) == GLFW_PRESS ? 1 : 0;
	right += glfwGetKey(m_wnd, GLFW_KEY_A) == GLFW_PRESS ? -1 : 0;

	m_camera.move(front, right, unit * m_deltaTime);
}

void MainWnd::calcProjection(int width, int height)
{
	float aspect;

	// 최소화 상태일땐 width == height == 0임.
	if (width == 0 || height == 0)
		aspect = 1.0f;
	else
		aspect = (float)width / height;

	m_projection = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 100.0f);
}

void MainWnd::onMouseCursorPos(double xpos, double ypos)
{
	if (m_isFirstMouse)
	{
		m_prevMouseX = (float)xpos;
		m_prevMouseY = (float)ypos;
		m_isFirstMouse = false;
	}
	else
	{
		int width, height;
		glfwGetFramebufferSize(m_wnd, &width, &height);
		if (!(width == 0 || height == 0))
		{
			const float maxPitch = glm::radians(75.0f);

			const float unit = glm::radians(60.0f);

			float dx = (float)xpos - m_prevMouseX;
			float dy = -((float)ypos - m_prevMouseY);

			float pitch = m_camera.getPitch() + (dy / height) * unit;
			float yaw = m_camera.getYaw() + (dx / width) * unit;

			if (pitch > maxPitch)
				pitch = maxPitch;
			else if (pitch < -maxPitch)
				pitch = -maxPitch;

			m_camera.setPitchYaw(pitch, yaw);

			m_prevMouseX = (float)xpos;
			m_prevMouseY = (float)ypos;
		}
	}
}

void MainWnd::onFrameBufferSize(int width, int height)
{
	// 최소화 상태일땐 width == height == 0임.
	if (!(width == 0 || height == 0))
	{
		glViewport(0, 0, width, height);
		calcProjection(width, height);
	}
}

void MainWnd::onWindowClose()
{
	// TODO: onWindowClose
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: DIndexIter.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 17:00:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_DBASE_INDEXITER_HXX_
#include "dbase/DIndexIter.hxx"
#endif
#ifndef _COM_SUN_STAR_SDB_SQLFILTEROPERATOR_HPP_
#include <com/sun/star/sdb/SQLFilterOperator.hpp>
#endif

using namespace ::com::sun::star::sdb;
using namespace connectivity;
using namespace connectivity::dbase;
using namespace connectivity::file;
using namespace ::com::sun::star::sdb;
//==================================================================
// OIndexIterator
//==================================================================
//------------------------------------------------------------------
OIndexIterator::~OIndexIterator()
{
    //  m_pIndex->UnLock();
    m_pIndex->release();
}

//------------------------------------------------------------------
ULONG OIndexIterator::First()
{
    return Find(TRUE);
}

//------------------------------------------------------------------
ULONG OIndexIterator::Next()
{
    return Find(FALSE);
}
//------------------------------------------------------------------
ULONG OIndexIterator::Find(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();

    ULONG nRes = STRING_NOTFOUND;
//  if (!m_pIndex->IsOpen())
//      return nRes;

    if (bFirst)
    {
        m_aRoot = m_pIndex->getRoot();
        m_aCurLeaf = NULL;
    }

    if (!m_pOperator)
    {
        // Vorbereitung , auf kleinstes Element positionieren
        if (bFirst)
        {
            ONDXPage* pPage = m_aRoot;
            while (pPage && !pPage->IsLeaf())
                pPage = pPage->GetChild(m_pIndex);

            m_aCurLeaf = pPage;
            m_nCurNode = NODE_NOTFOUND;
        }
        ONDXKey* pKey = GetNextKey();
        nRes = pKey ? pKey->GetRecord() : STRING_NOTFOUND;
    }
    else if (m_pOperator->IsA(TYPE(OOp_ISNOTNULL)))
        nRes = GetNotNull(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_ISNULL)))
        nRes = GetNull(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_LIKE)))
        nRes = GetLike(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_COMPARE)))
        nRes = GetCompare(bFirst);

    return nRes;
}

//------------------------------------------------------------------
ONDXKey* OIndexIterator::GetFirstKey(ONDXPage* pPage, const OOperand& rKey)
{
    // sucht den vorgegeben key
    // Besonderheit: gelangt der Algorithmus ans Ende
    // wird immer die aktuelle Seite und die Knotenposition vermerkt
    // auf die die Bedingung <= zutrifft
    // dieses findet beim Insert besondere Beachtung
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
    USHORT i = 0;

    if (pPage->IsLeaf())
    {
        // im blatt wird die eigentliche Operation ausgefuehrt, sonst die temp. (>)
        while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(),&rKey))
               i++;
    }
    else
        while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(),&rKey))
               i++;

    ONDXKey* pFoundKey = NULL;
    if (!pPage->IsLeaf())
    {
        // weiter absteigen
        ONDXPagePtr aPage = (i==0) ? pPage->GetChild(m_pIndex)
                                     : ((*pPage)[i-1]).GetChild(m_pIndex, pPage);
        pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : NULL;
    }
    else if (i == pPage->Count())
    {
        pFoundKey = NULL;
    }
    else
    {
        pFoundKey = &(*pPage)[i].GetKey();
        if (!m_pOperator->operate(pFoundKey,&rKey))
            pFoundKey = NULL;

        m_aCurLeaf = pPage;
        m_nCurNode = pFoundKey ? i : i - 1;
    }
    return pFoundKey;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetCompare(BOOL bFirst)
{
    ONDXKey* pKey = NULL;
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    sal_Int32 ePredicateType = PTR_CAST(file::OOp_COMPARE,m_pOperator)->getPredicateType();

    if (bFirst)
    {
        // Vorbereitung , auf kleinstes Element positionieren
        ONDXPage* pPage = m_aRoot;
        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
            case SQLFilterOperator::LESS:
            case SQLFilterOperator::LESS_EQUAL:
                while (pPage && !pPage->IsLeaf())
                    pPage = pPage->GetChild(m_pIndex);

                m_aCurLeaf = pPage;
                m_nCurNode = NODE_NOTFOUND;
        }

        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
                while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand));
                break;
            case SQLFilterOperator::LESS:
                while ((pKey = GetNextKey()) && pKey->getValue().isNull());
                break;
            case SQLFilterOperator::LESS_EQUAL:
                while (pKey = GetNextKey());
                break;
            case SQLFilterOperator::GREATER_EQUAL:
            case SQLFilterOperator::EQUAL:
                pKey = GetFirstKey(m_aRoot,*m_pOperand);
                break;
            case SQLFilterOperator::GREATER:
                if (!(pKey = GetFirstKey(m_aRoot,*m_pOperand)))
                    while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand));
        }
    }
    else
    {
        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
                while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand))
                    ;
                break;
            case SQLFilterOperator::LESS:
            case SQLFilterOperator::LESS_EQUAL:
            case SQLFilterOperator::EQUAL:
                if (!(pKey = GetNextKey()) || !m_pOperator->operate(pKey,m_pOperand))
                {
                    pKey = NULL;
                    m_aCurLeaf = NULL;
                }
                break;
            case SQLFilterOperator::GREATER_EQUAL:
            case SQLFilterOperator::GREATER:
                pKey = GetNextKey();
        }
    }

    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetLike(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        ONDXPage* pPage = m_aRoot;

        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = NODE_NOTFOUND;
    }

    ONDXKey* pKey;
    while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand))
        ;
    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetNull(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        ONDXPage* pPage = m_aRoot;
        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = NODE_NOTFOUND;
    }

    ONDXKey* pKey;
    if (!(pKey = GetNextKey()) || !pKey->getValue().isNull())
    {
        pKey = NULL;
        m_aCurLeaf = NULL;
    }
    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetNotNull(BOOL bFirst)
{
    ONDXKey* pKey;
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        // erst alle NULL werte abklappern
        for (ULONG nRec = GetNull(bFirst);
             nRec != STRING_NOTFOUND;
             nRec = GetNull(FALSE))
                 ;
        pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
    }
    else
        pKey = GetNextKey();

    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ONDXKey* OIndexIterator::GetNextKey()
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
    {
        ONDXPage* pPage = m_aCurLeaf;
        // naechste Seite suchen
        while (pPage)
        {
            ONDXPage* pParentPage = pPage->GetParent();
            if (pParentPage)
            {
                USHORT nPos = pParentPage->Search(pPage);
                if (nPos != pParentPage->Count() - 1)
                {   // Seite gefunden
                    pPage = (*pParentPage)[nPos+1].GetChild(m_pIndex,pParentPage);
                    break;
                }
            }
            pPage = pParentPage;
        }

        // jetzt wieder zum Blatt
        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = 0;
    }
    return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.5.132); FILE MERGED 2005/09/05 17:23:26 rt 1.5.132.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DIndexIter.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 05:38:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_DBASE_INDEXITER_HXX_
#include "dbase/DIndexIter.hxx"
#endif
#ifndef _COM_SUN_STAR_SDB_SQLFILTEROPERATOR_HPP_
#include <com/sun/star/sdb/SQLFilterOperator.hpp>
#endif

using namespace ::com::sun::star::sdb;
using namespace connectivity;
using namespace connectivity::dbase;
using namespace connectivity::file;
using namespace ::com::sun::star::sdb;
//==================================================================
// OIndexIterator
//==================================================================
//------------------------------------------------------------------
OIndexIterator::~OIndexIterator()
{
    //  m_pIndex->UnLock();
    m_pIndex->release();
}

//------------------------------------------------------------------
ULONG OIndexIterator::First()
{
    return Find(TRUE);
}

//------------------------------------------------------------------
ULONG OIndexIterator::Next()
{
    return Find(FALSE);
}
//------------------------------------------------------------------
ULONG OIndexIterator::Find(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();

    ULONG nRes = STRING_NOTFOUND;
//  if (!m_pIndex->IsOpen())
//      return nRes;

    if (bFirst)
    {
        m_aRoot = m_pIndex->getRoot();
        m_aCurLeaf = NULL;
    }

    if (!m_pOperator)
    {
        // Vorbereitung , auf kleinstes Element positionieren
        if (bFirst)
        {
            ONDXPage* pPage = m_aRoot;
            while (pPage && !pPage->IsLeaf())
                pPage = pPage->GetChild(m_pIndex);

            m_aCurLeaf = pPage;
            m_nCurNode = NODE_NOTFOUND;
        }
        ONDXKey* pKey = GetNextKey();
        nRes = pKey ? pKey->GetRecord() : STRING_NOTFOUND;
    }
    else if (m_pOperator->IsA(TYPE(OOp_ISNOTNULL)))
        nRes = GetNotNull(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_ISNULL)))
        nRes = GetNull(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_LIKE)))
        nRes = GetLike(bFirst);
    else if (m_pOperator->IsA(TYPE(OOp_COMPARE)))
        nRes = GetCompare(bFirst);

    return nRes;
}

//------------------------------------------------------------------
ONDXKey* OIndexIterator::GetFirstKey(ONDXPage* pPage, const OOperand& rKey)
{
    // sucht den vorgegeben key
    // Besonderheit: gelangt der Algorithmus ans Ende
    // wird immer die aktuelle Seite und die Knotenposition vermerkt
    // auf die die Bedingung <= zutrifft
    // dieses findet beim Insert besondere Beachtung
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    OOp_COMPARE aTempOp(SQLFilterOperator::GREATER);
    USHORT i = 0;

    if (pPage->IsLeaf())
    {
        // im blatt wird die eigentliche Operation ausgefuehrt, sonst die temp. (>)
        while (i < pPage->Count() && !m_pOperator->operate(&((*pPage)[i]).GetKey(),&rKey))
               i++;
    }
    else
        while (i < pPage->Count() && !aTempOp.operate(&((*pPage)[i]).GetKey(),&rKey))
               i++;

    ONDXKey* pFoundKey = NULL;
    if (!pPage->IsLeaf())
    {
        // weiter absteigen
        ONDXPagePtr aPage = (i==0) ? pPage->GetChild(m_pIndex)
                                     : ((*pPage)[i-1]).GetChild(m_pIndex, pPage);
        pFoundKey = aPage.Is() ? GetFirstKey(aPage, rKey) : NULL;
    }
    else if (i == pPage->Count())
    {
        pFoundKey = NULL;
    }
    else
    {
        pFoundKey = &(*pPage)[i].GetKey();
        if (!m_pOperator->operate(pFoundKey,&rKey))
            pFoundKey = NULL;

        m_aCurLeaf = pPage;
        m_nCurNode = pFoundKey ? i : i - 1;
    }
    return pFoundKey;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetCompare(BOOL bFirst)
{
    ONDXKey* pKey = NULL;
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    sal_Int32 ePredicateType = PTR_CAST(file::OOp_COMPARE,m_pOperator)->getPredicateType();

    if (bFirst)
    {
        // Vorbereitung , auf kleinstes Element positionieren
        ONDXPage* pPage = m_aRoot;
        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
            case SQLFilterOperator::LESS:
            case SQLFilterOperator::LESS_EQUAL:
                while (pPage && !pPage->IsLeaf())
                    pPage = pPage->GetChild(m_pIndex);

                m_aCurLeaf = pPage;
                m_nCurNode = NODE_NOTFOUND;
        }

        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
                while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand));
                break;
            case SQLFilterOperator::LESS:
                while ((pKey = GetNextKey()) && pKey->getValue().isNull());
                break;
            case SQLFilterOperator::LESS_EQUAL:
                while (pKey = GetNextKey());
                break;
            case SQLFilterOperator::GREATER_EQUAL:
            case SQLFilterOperator::EQUAL:
                pKey = GetFirstKey(m_aRoot,*m_pOperand);
                break;
            case SQLFilterOperator::GREATER:
                if (!(pKey = GetFirstKey(m_aRoot,*m_pOperand)))
                    while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand));
        }
    }
    else
    {
        switch (ePredicateType)
        {
            case SQLFilterOperator::NOT_EQUAL:
                while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand))
                    ;
                break;
            case SQLFilterOperator::LESS:
            case SQLFilterOperator::LESS_EQUAL:
            case SQLFilterOperator::EQUAL:
                if (!(pKey = GetNextKey()) || !m_pOperator->operate(pKey,m_pOperand))
                {
                    pKey = NULL;
                    m_aCurLeaf = NULL;
                }
                break;
            case SQLFilterOperator::GREATER_EQUAL:
            case SQLFilterOperator::GREATER:
                pKey = GetNextKey();
        }
    }

    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetLike(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        ONDXPage* pPage = m_aRoot;

        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = NODE_NOTFOUND;
    }

    ONDXKey* pKey;
    while ((pKey = GetNextKey()) && !m_pOperator->operate(pKey,m_pOperand))
        ;
    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetNull(BOOL bFirst)
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        ONDXPage* pPage = m_aRoot;
        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = NODE_NOTFOUND;
    }

    ONDXKey* pKey;
    if (!(pKey = GetNextKey()) || !pKey->getValue().isNull())
    {
        pKey = NULL;
        m_aCurLeaf = NULL;
    }
    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ULONG OIndexIterator::GetNotNull(BOOL bFirst)
{
    ONDXKey* pKey;
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (bFirst)
    {
        // erst alle NULL werte abklappern
        for (ULONG nRec = GetNull(bFirst);
             nRec != STRING_NOTFOUND;
             nRec = GetNull(FALSE))
                 ;
        pKey = m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
    }
    else
        pKey = GetNextKey();

    return pKey ? pKey->GetRecord() : STRING_NOTFOUND;
}

//------------------------------------------------------------------
ONDXKey* OIndexIterator::GetNextKey()
{
    //  ONDXIndex* m_pIndex = GetNDXIndex();
    if (m_aCurLeaf.Is() && ((++m_nCurNode) >= m_aCurLeaf->Count()))
    {
        ONDXPage* pPage = m_aCurLeaf;
        // naechste Seite suchen
        while (pPage)
        {
            ONDXPage* pParentPage = pPage->GetParent();
            if (pParentPage)
            {
                USHORT nPos = pParentPage->Search(pPage);
                if (nPos != pParentPage->Count() - 1)
                {   // Seite gefunden
                    pPage = (*pParentPage)[nPos+1].GetChild(m_pIndex,pParentPage);
                    break;
                }
            }
            pPage = pParentPage;
        }

        // jetzt wieder zum Blatt
        while (pPage && !pPage->IsLeaf())
            pPage = pPage->GetChild(m_pIndex);

        m_aCurLeaf = pPage;
        m_nCurNode = 0;
    }
    return m_aCurLeaf.Is() ? &(*m_aCurLeaf)[m_nCurNode].GetKey() : NULL;
}

<|endoftext|>


<commit_before>//
// Name:		StartupDlg.cpp
//
// Copyright (c) 2001-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation "StartupDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#include "wx/image.h"

#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif

#if defined(UNIX)
#  include <X11/Xlib.h>
#  include <X11/Xutil.h>
#  include <GL/glx.h>
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "vtlib/core/TerrainScene.h"

#include "StartupDlg.h"
#include "../Enviro.h"	// for GetCurrentTerrain
#include "../Options.h"
#include "vtdata/boost/directory.h"
#include "vtdata/vtLog.h"

#include "app.h"
#include "TParamsDlg.h"

//
// This function is used to find all files in a given directory,
// and if they match a wildcard, add them to a combo box.
//
void AddFilenamesToComboBox(wxComboBox *box, const char *directory,
	const char *wildcard, int omit_chars)
{
	VTLOG(" AddFilenamesToComboBox '%s', '%s':", directory, wildcard);

	using namespace boost::filesystem;
	int entries = 0, matches = 0;

	wxString2 wildstr = wildcard;
	for (dir_it it((const char *)directory); it != dir_it(); ++it)
	{
		entries++;
		std::string name1 = *it;
		//		VTLOG("   entry: '%s'", name1.c_str());
		if (get<is_hidden>(it) || get<is_directory>(it))
			continue;

		wxString2 name = name1.c_str();
		if (name.Matches(wildstr))
		{
			if (omit_chars)
				box->Append(name.Left(name.Length()-omit_chars));
			else
				box->Append(name);
			matches++;
		}
	}
	VTLOG(" %d entries, %d matches\n", entries, matches);
}

//
// Helper: find the largest texture size supported by OpenGL
//
#ifdef WIN32
static void ShowOGLInfo(bool bLog, HDC hdc)
#else
static void ShowOGLInfo(bool bLog)
#endif
{
#if defined(WIN32)
	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd
		1,						// version number
		PFD_DRAW_TO_WINDOW |	// support window
		PFD_SUPPORT_OPENGL |	// support OpenGL
		PFD_DOUBLEBUFFER,		// double buffered
		PFD_TYPE_RGBA,			// RGBA type
		24,						// 24-bit color depth
		0, 0, 0, 0, 0, 0,		// color bits ignored
		0, 0, 0,				// no alpha buffer
		0, 0, 0, 0,				// accum bits ignored
		32, 0, 0,				// 32-bit z-buffer
		PFD_MAIN_PLANE,			// main layer
		0, 0, 0, 0				// reserved, layer masks ignored
	};
	int  iPixelFormat;

	// get the best available match of pixel format for the device context
	iPixelFormat = ChoosePixelFormat(hdc, &pfd);
	// make that the pixel format of the device context
	SetPixelFormat(hdc, iPixelFormat, &pfd);

	HGLRC device = wglCreateContext(hdc);
	if (device == NULL)
	{
		DWORD lasterror = GetLastError();
		// 2000 The pixel format is invalid.  ERROR_INVALID_PIXEL_FORMAT
	}
	wglMakeCurrent(hdc, device);
#elif defined(UNIX)
	static int dblBuf[] =  {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
		GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1,
		GLX_DOUBLEBUFFER, None};
	Display *dpy;
	Window win;
	XVisualInfo *vi;
	Colormap cmap;
	XSetWindowAttributes swa;
	GLXContext cx;
	XEvent event;
	Bool needRedraw = False, recalcModelView = True;
	int dummy;

	dpy = XOpenDisplay(NULL);
	if (dpy == NULL)
		wxFatalError( "could not open display" );

	if (!glXQueryExtension(dpy, &dummy, &dummy))
		wxFatalError( "X server has no OpenGL GLX extension" );

	vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
	if (vi == NULL)
		wxFatalError( "no RGB visual with double and depth buffer" );
	if (vi->c_class != TrueColor)
		wxFatalError( "TrueColor visual required for this program" );

	cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
			vi->visual, AllocNone);
	swa.colormap = cmap;
	swa.border_pixel = 0;
	swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask;
	win = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
			0, 0, 300, 300, 0, vi->depth,
			InputOutput, vi->visual,
			CWBorderPixel | CWColormap | CWEventMask, &swa);

	XSetStandardProperties(dpy, win, "test", "test",
		None, NULL, 0, NULL);

	cx = glXCreateContext(dpy, vi, None, True);
	if (cx == NULL)
		wxFatalError( "could not create rendering context" );

	glXMakeCurrent(dpy, win, cx);
#else
#  error "I don't know this platform."
#endif

	GLint value;
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
	GLenum error = glGetError();
	if (error == GL_INVALID_OPERATION)
		value = 0;

	if (bLog)
	{
		VTLOG("\tOpenGL Version: %hs\n\tVendor: %hs\n\tRenderer: %hs\n"
			"\tMaximum Texture Dimension: %d\n",
			glGetString(GL_VERSION), glGetString(GL_VENDOR),
			glGetString(GL_RENDERER), value);
	}
	else
	{
		wxString2 str;
		str.Printf(_T("OpenGL Version: %hs\nVendor: %hs\nRenderer: %hs\n")
			_T("Maximum Texture Dimension: %d\nExtensions: %hs"),
			glGetString(GL_VERSION), glGetString(GL_VENDOR),
			glGetString(GL_RENDERER), value, glGetString(GL_EXTENSIONS));

		wxDialog dlg(NULL, -1, _T("OpenGL Info"), wxDefaultPosition);
		TextDialogFunc(&dlg, true);
		wxTextCtrl* pText = (wxTextCtrl*) dlg.FindWindow( ID_TEXT );
		pText->SetValue(str);

		dlg.ShowModal();
	}

#ifdef WIN32
	wglDeleteContext(device);
#elif defined(UNIX)
	glXDestroyContext(dpy, cx);
	XDestroyWindow(dpy, win);
	XCloseDisplay(dpy);
#endif
}

// WDR: class implementations

//----------------------------------------------------------------------------
// StartupDlg
//----------------------------------------------------------------------------

void StartupDlg::GetOptionsFrom(EnviroOptions &opt)
{
	m_bStartEarth = (opt.m_bEarthView == TRUE);
	m_bStartTerrain = !opt.m_bEarthView;
	m_strImage = wxString::FromAscii((const char *)opt.m_strImage);
	m_strTName = wxString::FromAscii((const char *)opt.m_strInitTerrain);
	m_bFullscreen = (opt.m_bFullscreen == TRUE);
	m_bHtmlpane = (opt.m_bHtmlpane == TRUE);
	m_bFloatingToolbar = (opt.m_bFloatingToolbar == TRUE);
	m_bSound = (opt.m_bSound == TRUE);
	m_bSpeedTest = (opt.m_bSpeedTest == TRUE);
	m_fPlantScale = opt.m_fPlantScale;
	m_bShadows = (opt.m_bShadows == TRUE);
}

void StartupDlg::PutOptionsTo(EnviroOptions &opt)
{
	opt.m_bEarthView = (m_bStartEarth == 1);
	opt.m_strImage = m_strImage.mb_str();
	opt.m_strInitTerrain = m_strTName.mb_str();
	opt.m_bFullscreen = m_bFullscreen;
	opt.m_bHtmlpane = m_bHtmlpane;
	opt.m_bFloatingToolbar = m_bFloatingToolbar;
	opt.m_bSound = m_bSound;
	opt.m_bSpeedTest = m_bSpeedTest;
	opt.m_fPlantScale = m_fPlantScale;
	opt.m_bShadows = m_bShadows;
}

void StartupDlg::UpdateState()
{
	m_psImage->Enable(m_bStartEarth);
	m_pImage->Enable(m_bStartEarth);
	m_pTName->Enable(m_bStartTerrain);
	m_pTSelect->Enable(m_bStartTerrain);
}

// WDR: event table for StartupDlg

BEGIN_EVENT_TABLE(StartupDlg,AutoDialog)
EVT_BUTTON( ID_TSELECT, StartupDlg::OnSelectTerrain )
EVT_BUTTON( wxID_OK, StartupDlg::OnOK )
EVT_BUTTON( ID_OPENGL, StartupDlg::OnOpenGLInfo )
EVT_RADIOBUTTON( ID_EARTHVIEW, StartupDlg::OnEarthView )
EVT_RADIOBUTTON( ID_TERRAIN, StartupDlg::OnTerrain )
EVT_BUTTON( ID_EDITPROP, StartupDlg::OnEditProp )
END_EVENT_TABLE()

StartupDlg::StartupDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
AutoDialog( parent, id, title, position, size, style )
{
	StartupDialogFunc( this, TRUE );
}

void StartupDlg::EditParameters(const char *filename)
{
	TParamsDlg dlg(this, -1, _T("Terrain Creation Parameters"), wxDefaultPosition);

	TParams Params;
	if (Params.LoadFromFile(filename))
		dlg.SetParams(Params);

	dlg.CenterOnParent();
	int result = dlg.ShowModal();
	if (result == wxID_OK)
	{
		dlg.GetParams(Params);
		if (!Params.SaveToFile(filename))
		{
			wxString str;
			str.Printf(_T("Couldn't save to file %hs.\n")
				_T("Please make sure the file is not read-only."), filename);
			wxMessageBox(str);
		}
	}
}

// WDR: handler implementations for StartupDlg

#if 0
void StartupDlg::OnSelectDataPath( wxCommandEvent &event )
{
	wxDirDialog dlg(this, _T("Please indicate your data directory"), m_strDataPath);
	if (dlg.ShowModal() == wxID_OK)
	{
		m_strDataPath = dlg.GetPath();
#if WIN32
		wxString path_separator = "\\";
#else
		wxString path_separator = "/";
#endif
		m_strDataPath += path_separator;
		TransferDataToWindow();
	}
}
#endif

void StartupDlg::OnEditProp( wxCommandEvent &event )
{
	vtTerrain *pTerr = GetTerrainScene()->FindTerrainByName(m_strTName.mb_str());
	if (pTerr)
		EditParameters(pTerr->GetParamFile());
}

void StartupDlg::OnTerrain( wxCommandEvent &event )
{
	TransferDataFromWindow();
	UpdateState();
}

void StartupDlg::OnEarthView( wxCommandEvent &event )
{
	TransferDataFromWindow();
	UpdateState();
}

void StartupDlg::OnOpenGLInfo( wxCommandEvent &event )
{
	// display OpenGL info, including max texture size
#ifdef WIN32
	wxClientDC wdc(this);
	HDC hdc = (HDC) wdc.GetHDC();
	ShowOGLInfo(false, hdc);
#else
	ShowOGLInfo(false);
#endif
}

void StartupDlg::OnOK( wxCommandEvent &event )
{
	wxDialog::OnOK(event);
}

void StartupDlg::OnInitDialog(wxInitDialogEvent& event)
{
	// display OpenGL info, including max texture size
#ifdef WIN32
	wxClientDC wdc(this);
	HDC hdc = (HDC) wdc.GetHDC();
	ShowOGLInfo(true, hdc);
#else
	ShowOGLInfo(true);
#endif

	vtTerrain *pTerr = GetTerrainScene()->FindTerrainByName(m_strTName.mb_str());
	if (pTerr)
		m_strTName = wxString::FromAscii(pTerr->GetName());
	else
		m_strTName = _T("none");

	m_pTName = GetTname();
	m_pTSelect = GetTselect();
	m_psImage = GetImagetext();
	m_pImage = GetImage();

	vtStringArray &paths = g_Options.m_DataPaths;
	for (unsigned int i = 0; i < paths.size(); i++)
	{
		vtString path = paths[i];
		path += "WholeEarth/";
		AddFilenamesToComboBox(m_pImage, path, "*_0106.png", 9);
		AddFilenamesToComboBox(m_pImage, path, "*_0106.jpg", 9);
	}
	int sel = m_pImage->FindString(m_strImage);
	if (sel != -1)
		m_pImage->SetSelection(sel);

	UpdateState();

	AddValidator(ID_EARTHVIEW, &m_bStartEarth);
	AddValidator(ID_TERRAIN, &m_bStartTerrain);

	AddValidator(ID_FULLSCREEN, &m_bFullscreen);
	AddValidator(ID_HTML_PANE, &m_bHtmlpane);
	AddValidator(ID_FLOATING, &m_bFloatingToolbar);
	AddValidator(ID_SOUND, &m_bSound);
	AddValidator(ID_SHADOWS, &m_bShadows);

	AddValidator(ID_TNAME, &m_strTName);
	AddValidator(ID_IMAGE, &m_strImage);
	AddNumValidator(ID_PLANTSIZE, &m_fPlantScale, 2);

	wxWindow::OnInitDialog(event);
}

void StartupDlg::OnSelectTerrain( wxCommandEvent &event )
{
	TransferDataFromWindow();

	AskForTerrainName(this, m_strTName);

	TransferDataToWindow();
}

<commit_msg>disabled log for add-filenames (too much...)<commit_after>//
// Name:		StartupDlg.cpp
//
// Copyright (c) 2001-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#ifdef __GNUG__
#pragma implementation "StartupDlg.cpp"
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#include "wx/image.h"

#ifndef WX_PRECOMP
#  include "wx/wx.h"
#endif

#if defined(UNIX)
#  include <X11/Xlib.h>
#  include <X11/Xutil.h>
#  include <GL/glx.h>
#endif

#include "vtlib/vtlib.h"
#include "vtlib/core/Terrain.h"
#include "vtlib/core/TerrainScene.h"

#include "StartupDlg.h"
#include "../Enviro.h"	// for GetCurrentTerrain
#include "../Options.h"
#include "vtdata/boost/directory.h"
#include "vtdata/vtLog.h"

#include "app.h"
#include "TParamsDlg.h"

//
// This function is used to find all files in a given directory,
// and if they match a wildcard, add them to a combo box.
//
void AddFilenamesToComboBox(wxComboBox *box, const char *directory,
	const char *wildcard, int omit_chars)
{
//	VTLOG(" AddFilenamesToComboBox '%s', '%s':", directory, wildcard);

	using namespace boost::filesystem;
	int entries = 0, matches = 0;

	wxString2 wildstr = wildcard;
	for (dir_it it((const char *)directory); it != dir_it(); ++it)
	{
		entries++;
		std::string name1 = *it;
		//		VTLOG("   entry: '%s'", name1.c_str());
		if (get<is_hidden>(it) || get<is_directory>(it))
			continue;

		wxString2 name = name1.c_str();
		if (name.Matches(wildstr))
		{
			if (omit_chars)
				box->Append(name.Left(name.Length()-omit_chars));
			else
				box->Append(name);
			matches++;
		}
	}
//	VTLOG(" %d entries, %d matches\n", entries, matches);
}

//
// Helper: find the largest texture size supported by OpenGL
//
#ifdef WIN32
static void ShowOGLInfo(bool bLog, HDC hdc)
#else
static void ShowOGLInfo(bool bLog)
#endif
{
#if defined(WIN32)
	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd
		1,						// version number
		PFD_DRAW_TO_WINDOW |	// support window
		PFD_SUPPORT_OPENGL |	// support OpenGL
		PFD_DOUBLEBUFFER,		// double buffered
		PFD_TYPE_RGBA,			// RGBA type
		24,						// 24-bit color depth
		0, 0, 0, 0, 0, 0,		// color bits ignored
		0, 0, 0,				// no alpha buffer
		0, 0, 0, 0,				// accum bits ignored
		32, 0, 0,				// 32-bit z-buffer
		PFD_MAIN_PLANE,			// main layer
		0, 0, 0, 0				// reserved, layer masks ignored
	};
	int  iPixelFormat;

	// get the best available match of pixel format for the device context
	iPixelFormat = ChoosePixelFormat(hdc, &pfd);
	// make that the pixel format of the device context
	SetPixelFormat(hdc, iPixelFormat, &pfd);

	HGLRC device = wglCreateContext(hdc);
	if (device == NULL)
	{
		DWORD lasterror = GetLastError();
		// 2000 The pixel format is invalid.  ERROR_INVALID_PIXEL_FORMAT
	}
	wglMakeCurrent(hdc, device);
#elif defined(UNIX)
	static int dblBuf[] =  {GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
		GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1,
		GLX_DOUBLEBUFFER, None};
	Display *dpy;
	Window win;
	XVisualInfo *vi;
	Colormap cmap;
	XSetWindowAttributes swa;
	GLXContext cx;
	XEvent event;
	Bool needRedraw = False, recalcModelView = True;
	int dummy;

	dpy = XOpenDisplay(NULL);
	if (dpy == NULL)
		wxFatalError( "could not open display" );

	if (!glXQueryExtension(dpy, &dummy, &dummy))
		wxFatalError( "X server has no OpenGL GLX extension" );

	vi = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
	if (vi == NULL)
		wxFatalError( "no RGB visual with double and depth buffer" );
	if (vi->c_class != TrueColor)
		wxFatalError( "TrueColor visual required for this program" );

	cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
			vi->visual, AllocNone);
	swa.colormap = cmap;
	swa.border_pixel = 0;
	swa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask;
	win = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
			0, 0, 300, 300, 0, vi->depth,
			InputOutput, vi->visual,
			CWBorderPixel | CWColormap | CWEventMask, &swa);

	XSetStandardProperties(dpy, win, "test", "test",
		None, NULL, 0, NULL);

	cx = glXCreateContext(dpy, vi, None, True);
	if (cx == NULL)
		wxFatalError( "could not create rendering context" );

	glXMakeCurrent(dpy, win, cx);
#else
#  error "I don't know this platform."
#endif

	GLint value;
	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
	GLenum error = glGetError();
	if (error == GL_INVALID_OPERATION)
		value = 0;

	if (bLog)
	{
		VTLOG("\tOpenGL Version: %hs\n\tVendor: %hs\n\tRenderer: %hs\n"
			"\tMaximum Texture Dimension: %d\n",
			glGetString(GL_VERSION), glGetString(GL_VENDOR),
			glGetString(GL_RENDERER), value);
	}
	else
	{
		wxString2 str;
		str.Printf(_T("OpenGL Version: %hs\nVendor: %hs\nRenderer: %hs\n")
			_T("Maximum Texture Dimension: %d\nExtensions: %hs"),
			glGetString(GL_VERSION), glGetString(GL_VENDOR),
			glGetString(GL_RENDERER), value, glGetString(GL_EXTENSIONS));

		wxDialog dlg(NULL, -1, _T("OpenGL Info"), wxDefaultPosition);
		TextDialogFunc(&dlg, true);
		wxTextCtrl* pText = (wxTextCtrl*) dlg.FindWindow( ID_TEXT );
		pText->SetValue(str);

		dlg.ShowModal();
	}

#ifdef WIN32
	wglDeleteContext(device);
#elif defined(UNIX)
	glXDestroyContext(dpy, cx);
	XDestroyWindow(dpy, win);
	XCloseDisplay(dpy);
#endif
}

// WDR: class implementations

//----------------------------------------------------------------------------
// StartupDlg
//----------------------------------------------------------------------------

void StartupDlg::GetOptionsFrom(EnviroOptions &opt)
{
	m_bStartEarth = (opt.m_bEarthView == TRUE);
	m_bStartTerrain = !opt.m_bEarthView;
	m_strImage = wxString::FromAscii((const char *)opt.m_strImage);
	m_strTName = wxString::FromAscii((const char *)opt.m_strInitTerrain);
	m_bFullscreen = (opt.m_bFullscreen == TRUE);
	m_bHtmlpane = (opt.m_bHtmlpane == TRUE);
	m_bFloatingToolbar = (opt.m_bFloatingToolbar == TRUE);
	m_bSound = (opt.m_bSound == TRUE);
	m_bSpeedTest = (opt.m_bSpeedTest == TRUE);
	m_fPlantScale = opt.m_fPlantScale;
	m_bShadows = (opt.m_bShadows == TRUE);
}

void StartupDlg::PutOptionsTo(EnviroOptions &opt)
{
	opt.m_bEarthView = (m_bStartEarth == 1);
	opt.m_strImage = m_strImage.mb_str();
	opt.m_strInitTerrain = m_strTName.mb_str();
	opt.m_bFullscreen = m_bFullscreen;
	opt.m_bHtmlpane = m_bHtmlpane;
	opt.m_bFloatingToolbar = m_bFloatingToolbar;
	opt.m_bSound = m_bSound;
	opt.m_bSpeedTest = m_bSpeedTest;
	opt.m_fPlantScale = m_fPlantScale;
	opt.m_bShadows = m_bShadows;
}

void StartupDlg::UpdateState()
{
	m_psImage->Enable(m_bStartEarth);
	m_pImage->Enable(m_bStartEarth);
	m_pTName->Enable(m_bStartTerrain);
	m_pTSelect->Enable(m_bStartTerrain);
}

// WDR: event table for StartupDlg

BEGIN_EVENT_TABLE(StartupDlg,AutoDialog)
EVT_BUTTON( ID_TSELECT, StartupDlg::OnSelectTerrain )
EVT_BUTTON( wxID_OK, StartupDlg::OnOK )
EVT_BUTTON( ID_OPENGL, StartupDlg::OnOpenGLInfo )
EVT_RADIOBUTTON( ID_EARTHVIEW, StartupDlg::OnEarthView )
EVT_RADIOBUTTON( ID_TERRAIN, StartupDlg::OnTerrain )
EVT_BUTTON( ID_EDITPROP, StartupDlg::OnEditProp )
END_EVENT_TABLE()

StartupDlg::StartupDlg( wxWindow *parent, wxWindowID id, const wxString &title,
	const wxPoint &position, const wxSize& size, long style ) :
AutoDialog( parent, id, title, position, size, style )
{
	StartupDialogFunc( this, TRUE );
}

void StartupDlg::EditParameters(const char *filename)
{
	TParamsDlg dlg(this, -1, _T("Terrain Creation Parameters"), wxDefaultPosition);

	TParams Params;
	if (Params.LoadFromFile(filename))
		dlg.SetParams(Params);

	dlg.CenterOnParent();
	int result = dlg.ShowModal();
	if (result == wxID_OK)
	{
		dlg.GetParams(Params);
		if (!Params.SaveToFile(filename))
		{
			wxString str;
			str.Printf(_T("Couldn't save to file %hs.\n")
				_T("Please make sure the file is not read-only."), filename);
			wxMessageBox(str);
		}
	}
}

// WDR: handler implementations for StartupDlg

#if 0
void StartupDlg::OnSelectDataPath( wxCommandEvent &event )
{
	wxDirDialog dlg(this, _T("Please indicate your data directory"), m_strDataPath);
	if (dlg.ShowModal() == wxID_OK)
	{
		m_strDataPath = dlg.GetPath();
#if WIN32
		wxString path_separator = "\\";
#else
		wxString path_separator = "/";
#endif
		m_strDataPath += path_separator;
		TransferDataToWindow();
	}
}
#endif

void StartupDlg::OnEditProp( wxCommandEvent &event )
{
	vtTerrain *pTerr = GetTerrainScene()->FindTerrainByName(m_strTName.mb_str());
	if (pTerr)
		EditParameters(pTerr->GetParamFile());
}

void StartupDlg::OnTerrain( wxCommandEvent &event )
{
	TransferDataFromWindow();
	UpdateState();
}

void StartupDlg::OnEarthView( wxCommandEvent &event )
{
	TransferDataFromWindow();
	UpdateState();
}

void StartupDlg::OnOpenGLInfo( wxCommandEvent &event )
{
	// display OpenGL info, including max texture size
#ifdef WIN32
	wxClientDC wdc(this);
	HDC hdc = (HDC) wdc.GetHDC();
	ShowOGLInfo(false, hdc);
#else
	ShowOGLInfo(false);
#endif
}

void StartupDlg::OnOK( wxCommandEvent &event )
{
	wxDialog::OnOK(event);
}

void StartupDlg::OnInitDialog(wxInitDialogEvent& event)
{
	// display OpenGL info, including max texture size
#ifdef WIN32
	wxClientDC wdc(this);
	HDC hdc = (HDC) wdc.GetHDC();
	ShowOGLInfo(true, hdc);
#else
	ShowOGLInfo(true);
#endif

	vtTerrain *pTerr = GetTerrainScene()->FindTerrainByName(m_strTName.mb_str());
	if (pTerr)
		m_strTName = wxString::FromAscii(pTerr->GetName());
	else
		m_strTName = _T("none");

	m_pTName = GetTname();
	m_pTSelect = GetTselect();
	m_psImage = GetImagetext();
	m_pImage = GetImage();

	vtStringArray &paths = g_Options.m_DataPaths;
	for (unsigned int i = 0; i < paths.size(); i++)
	{
		vtString path = paths[i];
		path += "WholeEarth/";
		AddFilenamesToComboBox(m_pImage, path, "*_0106.png", 9);
		AddFilenamesToComboBox(m_pImage, path, "*_0106.jpg", 9);
	}
	int sel = m_pImage->FindString(m_strImage);
	if (sel != -1)
		m_pImage->SetSelection(sel);

	UpdateState();

	AddValidator(ID_EARTHVIEW, &m_bStartEarth);
	AddValidator(ID_TERRAIN, &m_bStartTerrain);

	AddValidator(ID_FULLSCREEN, &m_bFullscreen);
	AddValidator(ID_HTML_PANE, &m_bHtmlpane);
	AddValidator(ID_FLOATING, &m_bFloatingToolbar);
	AddValidator(ID_SOUND, &m_bSound);
	AddValidator(ID_SHADOWS, &m_bShadows);

	AddValidator(ID_TNAME, &m_strTName);
	AddValidator(ID_IMAGE, &m_strImage);
	AddNumValidator(ID_PLANTSIZE, &m_fPlantScale, 2);

	wxWindow::OnInitDialog(event);
}

void StartupDlg::OnSelectTerrain( wxCommandEvent &event )
{
	TransferDataFromWindow();

	AskForTerrainName(this, m_strTName);

	TransferDataToWindow();
}

<|endoftext|>