<commit_before>// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************

#include "stdafx.h"
#include "WinRTMidi.h"
#include <iostream>
#include <string>

using namespace std;
using namespace WinRT;

CRITICAL_SECTION gCriticalSection;

// WinRTMidi DLL function pointers
WinRTWatcherPortCountFunc   gWatcherPortCountFunc = nullptr;
WinRTWatcherPortNameFunc    gWatcherPortNameFunc = nullptr;
WinRTWatcherPortTypeFunc    gWatcherPortTypeFunc = nullptr;
WinRTMidiInitializeFunc     gMidiInitFunc = nullptr;
WinRTMidiFreeFunc           gMidiFreeFunc = nullptr;
WinRTMidiGetPortWatcherFunc gMidiGetPortWatcher = nullptr;
WinRTMidiInPortOpenFunc     gMidiInPortOpenFunc = nullptr;
WinRTMidiInPortFreeFunc     gMidiInPortFreeFunc = nullptr;
WinRTMidiOutPortOpenFunc    gMidiOutPortOpenFunc = nullptr;
WinRTMidiOutPortFreeFunc    gMidiOutPortFreeFunc = nullptr;
WinRTMidiOutPortSendFunc    gMidiOutPortSendFunc = nullptr;

// Midi Out port
WinRTMidiOutPortPtr gMidiOutPort = nullptr;

void printPortNames(const WinRTMidiPortWatcherPtr watcher)
{
    if (watcher == nullptr)
    {
        return;
    }

    WinRTMidiPortType type = gWatcherPortTypeFunc(watcher);
    if (type == In)
    {
        cout << "MIDI In Ports" << endl;
    }
    else
    {
        cout << "MIDI Out Ports" << endl;
    }

    int nPorts = gWatcherPortCountFunc(watcher);
    for (int i = 0; i < nPorts; i++)
    {
        const char* name = gWatcherPortNameFunc(watcher, i);
        cout << i << ": " << gWatcherPortNameFunc(watcher, i) << endl;
    }

    cout << endl;
}

void midiPortChangedCallback(const WinRTMidiPortWatcherPtr portWatcher, WinRTMidiPortUpdateType update)
{
    EnterCriticalSection(&gCriticalSection);
    string portName = gWatcherPortTypeFunc(portWatcher) == In ? "In" : "Out";

    switch (update)
    {
    case PortAdded:
        cout << "***MIDI " << portName << " port added***" << endl;
        break;

    case PortRemoved:
        cout << "***MIDI " << portName << " port removed***" << endl;
        break;

    case EnumerationComplete:
        cout << "***MIDI " << portName << " port enumeration complete***" << endl;
        break;
    }

    printPortNames(portWatcher);
    LeaveCriticalSection(&gCriticalSection);
}

void midiInCallback(const WinRTMidiInPortPtr port, double timeStamp, const unsigned char* message, unsigned int nBytes)
{
    if (gMidiOutPort != nullptr)
    {
        gMidiOutPortSendFunc(gMidiOutPort, message, nBytes);
    }

    EnterCriticalSection(&gCriticalSection);
    for (unsigned int i = 0; i < nBytes; i++)
    {
        cout << "Byte " << i << " = " << (int)message[i] << ", ";
    }

    if (nBytes > 0)
    {
        cout << "timestamp = " << timeStamp << endl;
    }
    LeaveCriticalSection(&gCriticalSection);
}

int main()
{
    HINSTANCE dllHandle = NULL;
    WinRTMidiPtr midiPtr = nullptr;
    WinRTMidiInPortPtr midiInPort = nullptr;

    //Load the WinRTMidi dll
    dllHandle = LoadLibrary(L"WinRTMidi.dll");
    if (NULL == dllHandle)
    {
        cout << "Unable to load WinRTMidi.dll" << endl;
        return -1;
    }

    InitializeCriticalSection(&gCriticalSection);

    // GetWinRTMidi DLL function pointers. Error checking needs to be added!

    //Get pointer to the WinRTMidiInitializeFunc function using GetProcAddress:
    gMidiInitFunc = reinterpret_cast<WinRTMidiInitializeFunc>(::GetProcAddress(dllHandle, "winrt_initialize_midi"));

    //Get pointer to the WinRTMidiFreeFunc function using GetProcAddress:
    gMidiFreeFunc = reinterpret_cast<WinRTMidiFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi"));

    //Get pointer to the WinRTMidiGetPortWatcherFunc function using GetProcAddress:
    gMidiGetPortWatcher = reinterpret_cast<WinRTMidiGetPortWatcherFunc>(::GetProcAddress(dllHandle, "winrt_get_portwatcher"));

    //Get pointer to the WinRTMidiInPortOpenFunc function using GetProcAddress:
    gMidiInPortOpenFunc = reinterpret_cast<WinRTMidiInPortOpenFunc>(::GetProcAddress(dllHandle, "winrt_open_midi_in_port"));

    //Get pointer to the WinRTMidiInPortFreeFunc function using GetProcAddress:
    gMidiInPortFreeFunc = reinterpret_cast<WinRTMidiInPortFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi_in_port"));

    //Get pointer to the WinRTMidiOutPortOpenFunc function using GetProcAddress:
    gMidiOutPortOpenFunc = reinterpret_cast<WinRTMidiOutPortOpenFunc>(::GetProcAddress(dllHandle, "winrt_open_midi_out_port"));

    //Get pointer to the WinRTMidiOutPortFreeFunc function using GetProcAddress:
    gMidiOutPortFreeFunc = reinterpret_cast<WinRTMidiOutPortFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi_out_port"));

    //Get pointer to the WinRTMidiOutPortSendFunc function using GetProcAddress:
    gMidiOutPortSendFunc = reinterpret_cast<WinRTMidiOutPortSendFunc>(::GetProcAddress(dllHandle, "winrt_midi_out_port_send"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortCountFunc = reinterpret_cast<WinRTWatcherPortCountFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_count"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortNameFunc = reinterpret_cast<WinRTWatcherPortNameFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_name"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortTypeFunc = reinterpret_cast<WinRTWatcherPortTypeFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_type"));

    // initialize Midi interface
    WinRTMidiErrorType result = gMidiInitFunc(midiPortChangedCallback, &midiPtr);
    if(result != WINRT_NO_ERROR)
    {
        cout << "Unable to initialize WinRTMidi" << endl;
        goto cleanup;
    }

    // open Midi In port 0
    result = gMidiInPortOpenFunc(midiPtr, 0, midiInCallback, &midiInPort);
    if (result != WINRT_NO_ERROR)
    {
        cout << "Unable to create Midi In port" << endl;
        goto cleanup;
    }

    // open Midi out port 0
    result = gMidiOutPortOpenFunc(midiPtr, 0, &gMidiOutPort);
    if (result != WINRT_NO_ERROR)
    {
        cout << "Unable to create Midi Out port" << endl;
        goto cleanup;
    }

    const WinRTMidiPortWatcherPtr watcher = gMidiGetPortWatcher(midiPtr, In);
    unsigned int numPorts = gWatcherPortCountFunc(watcher);
    const char* name = gWatcherPortNameFunc(watcher, 0);

    // process midi until user presses key on keyboard
    char c = getchar();

cleanup:
    // clean up midi objects
    gMidiOutPortFreeFunc(gMidiOutPort);
    gMidiInPortFreeFunc(midiInPort);
    gMidiFreeFunc(midiPtr);

    //Free the library:
    FreeLibrary(dllHandle);

    DeleteCriticalSection(&gCriticalSection);

    return 0;
}<commit_msg>code formating<commit_after>// ******************************************************************
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THE CODE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
// THE CODE OR THE USE OR OTHER DEALINGS IN THE CODE.
// ******************************************************************

#include "stdafx.h"
#include "WinRTMidi.h"
#include <iostream>
#include <string>

using namespace std;
using namespace WinRT;

CRITICAL_SECTION gCriticalSection;

// WinRTMidi DLL function pointers
WinRTWatcherPortCountFunc   gWatcherPortCountFunc = nullptr;
WinRTWatcherPortNameFunc    gWatcherPortNameFunc = nullptr;
WinRTWatcherPortTypeFunc    gWatcherPortTypeFunc = nullptr;
WinRTMidiInitializeFunc     gMidiInitFunc = nullptr;
WinRTMidiFreeFunc           gMidiFreeFunc = nullptr;
WinRTMidiGetPortWatcherFunc gMidiGetPortWatcher = nullptr;
WinRTMidiInPortOpenFunc     gMidiInPortOpenFunc = nullptr;
WinRTMidiInPortFreeFunc     gMidiInPortFreeFunc = nullptr;
WinRTMidiOutPortOpenFunc    gMidiOutPortOpenFunc = nullptr;
WinRTMidiOutPortFreeFunc    gMidiOutPortFreeFunc = nullptr;
WinRTMidiOutPortSendFunc    gMidiOutPortSendFunc = nullptr;

// Midi Out port
WinRTMidiOutPortPtr gMidiOutPort = nullptr;

void printPortNames(const WinRTMidiPortWatcherPtr watcher)
{
    if (watcher == nullptr)
    {
        return;
    }

    WinRTMidiPortType type = gWatcherPortTypeFunc(watcher);
    if (type == In)
    {
        cout << "MIDI In Ports" << endl;
    }
    else
    {
        cout << "MIDI Out Ports" << endl;
    }

    int nPorts = gWatcherPortCountFunc(watcher);
    for (int i = 0; i < nPorts; i++)
    {
        const char* name = gWatcherPortNameFunc(watcher, i);
        cout << i << ": " << gWatcherPortNameFunc(watcher, i) << endl;
    }

    cout << endl;
}

void midiPortChangedCallback(const WinRTMidiPortWatcherPtr portWatcher, WinRTMidiPortUpdateType update)
{
    EnterCriticalSection(&gCriticalSection);
    string portName = gWatcherPortTypeFunc(portWatcher) == In ? "In" : "Out";

    switch (update)
    {
    case PortAdded:
        cout << "***MIDI " << portName << " port added***" << endl;
        break;

    case PortRemoved:
        cout << "***MIDI " << portName << " port removed***" << endl;
        break;

    case EnumerationComplete:
        cout << "***MIDI " << portName << " port enumeration complete***" << endl;
        break;
    }

    printPortNames(portWatcher);
    LeaveCriticalSection(&gCriticalSection);
}

void midiInCallback(const WinRTMidiInPortPtr port, double timeStamp, const unsigned char* message, unsigned int nBytes)
{
    if (gMidiOutPort != nullptr)
    {
        gMidiOutPortSendFunc(gMidiOutPort, message, nBytes);
    }

    EnterCriticalSection(&gCriticalSection);
    for (unsigned int i = 0; i < nBytes; i++)
    {
        cout << "Byte " << i << " = " << (int)message[i] << ", ";
    }

    if (nBytes > 0)
    {
        cout << "timestamp = " << timeStamp << endl;
    }
    LeaveCriticalSection(&gCriticalSection);
}

int main()
{
    HINSTANCE dllHandle = NULL;
    WinRTMidiPtr midiPtr = nullptr;
    WinRTMidiInPortPtr midiInPort = nullptr;

    //Load the WinRTMidi dll
    dllHandle = LoadLibrary(L"WinRTMidi.dll");
    if (NULL == dllHandle)
    {
        cout << "Unable to load WinRTMidi.dll" << endl;
        return -1;
    }

    InitializeCriticalSection(&gCriticalSection);

    // GetWinRTMidi DLL function pointers. Error checking needs to be added!
    //Get pointer to the WinRTMidiInitializeFunc function using GetProcAddress:
    gMidiInitFunc = reinterpret_cast<WinRTMidiInitializeFunc>(::GetProcAddress(dllHandle, "winrt_initialize_midi"));

    //Get pointer to the WinRTMidiFreeFunc function using GetProcAddress:
    gMidiFreeFunc = reinterpret_cast<WinRTMidiFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi"));

    //Get pointer to the WinRTMidiGetPortWatcherFunc function using GetProcAddress:
    gMidiGetPortWatcher = reinterpret_cast<WinRTMidiGetPortWatcherFunc>(::GetProcAddress(dllHandle, "winrt_get_portwatcher"));

    //Get pointer to the WinRTMidiInPortOpenFunc function using GetProcAddress:
    gMidiInPortOpenFunc = reinterpret_cast<WinRTMidiInPortOpenFunc>(::GetProcAddress(dllHandle, "winrt_open_midi_in_port"));

    //Get pointer to the WinRTMidiInPortFreeFunc function using GetProcAddress:
    gMidiInPortFreeFunc = reinterpret_cast<WinRTMidiInPortFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi_in_port"));

    //Get pointer to the WinRTMidiOutPortOpenFunc function using GetProcAddress:
    gMidiOutPortOpenFunc = reinterpret_cast<WinRTMidiOutPortOpenFunc>(::GetProcAddress(dllHandle, "winrt_open_midi_out_port"));

    //Get pointer to the WinRTMidiOutPortFreeFunc function using GetProcAddress:
    gMidiOutPortFreeFunc = reinterpret_cast<WinRTMidiOutPortFreeFunc>(::GetProcAddress(dllHandle, "winrt_free_midi_out_port"));

    //Get pointer to the WinRTMidiOutPortSendFunc function using GetProcAddress:
    gMidiOutPortSendFunc = reinterpret_cast<WinRTMidiOutPortSendFunc>(::GetProcAddress(dllHandle, "winrt_midi_out_port_send"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortCountFunc = reinterpret_cast<WinRTWatcherPortCountFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_count"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortNameFunc = reinterpret_cast<WinRTWatcherPortNameFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_name"));

    //Get pointer to the WinRTWatcherPortCountFunc function using GetProcAddress:
    gWatcherPortTypeFunc = reinterpret_cast<WinRTWatcherPortTypeFunc>(::GetProcAddress(dllHandle, "winrt_watcher_get_port_type"));

    // initialize Midi interface
    WinRTMidiErrorType result = gMidiInitFunc(midiPortChangedCallback, &midiPtr);
    if(result != WINRT_NO_ERROR)
    {
        cout << "Unable to initialize WinRTMidi" << endl;
        goto cleanup;
    }

    // open midi in port 0
    result = gMidiInPortOpenFunc(midiPtr, 0, midiInCallback, &midiInPort);
    if (result != WINRT_NO_ERROR)
    {
        cout << "Unable to create Midi In port" << endl;
        goto cleanup;
    }

    // open midi out port 0
    result = gMidiOutPortOpenFunc(midiPtr, 0, &gMidiOutPort);
    if (result != WINRT_NO_ERROR)
    {
        cout << "Unable to create Midi Out port" << endl;
        goto cleanup;
    }

    // example on how get midi port info
    const WinRTMidiPortWatcherPtr watcher = gMidiGetPortWatcher(midiPtr, In);
    if (watcher != nullptr)
    {
        unsigned int numPorts = gWatcherPortCountFunc(watcher);
        if (numPorts > 0)
        {
            const char* name = gWatcherPortNameFunc(watcher, 0);
        }
    }

    // process midi until user presses key on keyboard
    char c = getchar();

cleanup:
    // clean up midi objects
    // okay to call with nullptrs
    gMidiOutPortFreeFunc(gMidiOutPort);
    gMidiInPortFreeFunc(midiInPort);
    gMidiFreeFunc(midiPtr);

    //Free the library:
    if (dllHandle)
    {
        FreeLibrary(dllHandle);
    }

    DeleteCriticalSection(&gCriticalSection);

    return 0;
}<|endoftext|>


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

// Interface header.
#include "diffuseedf.h"

// appleseed.renderer headers.
#include "renderer/global/globaltypes.h"
#include "renderer/modeling/input/inputarray.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/sampling.h"
#include "foundation/math/scalar.h"
#include "foundation/math/vector.h"
#include "foundation/platform/compiler.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <cassert>

using namespace foundation;

namespace renderer
{

namespace
{
    //
    // Diffuse EDF.
    //

    const char* Model = "diffuse_edf";

    class DiffuseEDF
      : public EDF
    {
      public:
        DiffuseEDF(
            const char*         name,
            const ParamArray&   params)
          : EDF(name, params)
        {
            m_inputs.declare("exitance", InputFormatSpectrum);
        }

        virtual void release() override
        {
            delete this;
        }

        virtual const char* get_model() const override
        {
            return Model;
        }

        virtual void sample(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector2d&     s,
            Vector3d&           outgoing,
            Spectrum&           value,
            double&             probability) const override
        {
            assert(is_normalized(geometric_normal));

            const Vector3d wo = sample_hemisphere_cosine(s);
            outgoing = shading_basis.transform_to_parent(wo);

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;

            probability = wo.y * RcpPi;
            assert(probability > 0.0);
        }

        virtual void evaluate(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Spectrum&           value) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
            {
                value.set(0.0f);
                return;
            }

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;
        }

        virtual void evaluate(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Spectrum&           value,
            double&             probability) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
            {
                value.set(0.0f);
                probability = 0.0;
                return;
            }

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;

            probability = cos_on * RcpPi;
        }

        virtual double evaluate_pdf(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
                return 0.0;

            return cos_on * RcpPi;
        }

      private:
        struct InputValues
        {
            Spectrum    m_exitance;         // radiant exitance, in W.m^-2
            Alpha       m_exitance_alpha;   // alpha channel of radiant exitance
        };
    };
}

//
// DiffuseEDFFactory class implementation.
//

const char* DiffuseEDFFactory::get_model() const
{
    return Model;
}

const char* DiffuseEDFFactory::get_human_readable_model() const
{
    return "Diffuse EDF";
}

DictionaryArray DiffuseEDFFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "exitance")
            .insert("label", "Exitance")
            .insert("widget", "entity_picker")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", ""));

    return definitions;
}

auto_release_ptr<EDF> DiffuseEDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<EDF>(new DiffuseEDF(name, params));
}

}   // namespace renderer
<commit_msg>added exitance multiplier to the perfectly diffuse EDF.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2012 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "diffuseedf.h"

// appleseed.renderer headers.
#include "renderer/global/globaltypes.h"
#include "renderer/modeling/input/inputarray.h"

// appleseed.foundation headers.
#include "foundation/math/basis.h"
#include "foundation/math/sampling.h"
#include "foundation/math/scalar.h"
#include "foundation/math/vector.h"
#include "foundation/platform/compiler.h"
#include "foundation/utility/containers/specializedarrays.h"

// Standard headers.
#include <cassert>

using namespace foundation;

namespace renderer
{

namespace
{
    //
    // Diffuse EDF.
    //

    const char* Model = "diffuse_edf";

    class DiffuseEDF
      : public EDF
    {
      public:
        DiffuseEDF(
            const char*         name,
            const ParamArray&   params)
          : EDF(name, params)
        {
            m_inputs.declare("exitance", InputFormatSpectrum);
            m_inputs.declare("exitance_multiplier", InputFormatScalar, "1.0");
        }

        virtual void release() override
        {
            delete this;
        }

        virtual const char* get_model() const override
        {
            return Model;
        }

        virtual void sample(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector2d&     s,
            Vector3d&           outgoing,
            Spectrum&           value,
            double&             probability) const override
        {
            assert(is_normalized(geometric_normal));

            const Vector3d wo = sample_hemisphere_cosine(s);
            outgoing = shading_basis.transform_to_parent(wo);

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;
            value *= static_cast<float>(values->m_exitance_multiplier);

            probability = wo.y * RcpPi;
            assert(probability > 0.0);
        }

        virtual void evaluate(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Spectrum&           value) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
            {
                value.set(0.0f);
                return;
            }

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;
            value *= static_cast<float>(values->m_exitance_multiplier);
        }

        virtual void evaluate(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing,
            Spectrum&           value,
            double&             probability) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
            {
                value.set(0.0f);
                probability = 0.0;
                return;
            }

            const InputValues* values = static_cast<const InputValues*>(data);
            value = values->m_exitance;
            value *= static_cast<float>(values->m_exitance_multiplier);

            probability = cos_on * RcpPi;
        }

        virtual double evaluate_pdf(
            const void*         data,
            const Vector3d&     geometric_normal,
            const Basis3d&      shading_basis,
            const Vector3d&     outgoing) const override
        {
            assert(is_normalized(geometric_normal));
            assert(is_normalized(outgoing));

            const double cos_on = dot(outgoing, shading_basis.get_normal());

            // No emission in or below the shading surface.
            if (cos_on <= 0.0)
                return 0.0;

            return cos_on * RcpPi;
        }

      private:
        struct InputValues
        {
            Spectrum    m_exitance;             // radiant exitance, in W.m^-2
            Alpha       m_exitance_alpha;       // unused
            double      m_exitance_multiplier;  // radiant exitance multiplier
        };
    };
}

//
// DiffuseEDFFactory class implementation.
//

const char* DiffuseEDFFactory::get_model() const
{
    return Model;
}

const char* DiffuseEDFFactory::get_human_readable_model() const
{
    return "Diffuse EDF";
}

DictionaryArray DiffuseEDFFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "exitance")
            .insert("label", "Exitance")
            .insert("widget", "entity_picker")
            .insert("entity_types",
                Dictionary()
                    .insert("color", "Colors")
                    .insert("texture_instance", "Textures"))
            .insert("use", "required")
            .insert("default", ""));

    definitions.push_back(
        Dictionary()
            .insert("name", "exitance_multiplier")
            .insert("label", "Exitance Multiplier")
            .insert("widget", "entity_picker")
            .insert("entity_types",
                Dictionary().insert("texture_instance", "Textures"))
            .insert("use", "optional")
            .insert("default", "1.0"));

    return definitions;
}

auto_release_ptr<EDF> DiffuseEDFFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return auto_release_ptr<EDF>(new DiffuseEDF(name, params));
}

}   // namespace renderer
<|endoftext|>


<commit_before>//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Copyright (C) 2008-2010 The PECOS Development Team
//
// Please see http://pecos.ices.utexas.edu for more information.
//
// This file is part of GRINS.
//
// GRINS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GRINS 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with GRINS.  If not, see <http://www.gnu.org/licenses/>.
//
//--------------------------------------------------------------------------
//
// Definitions for the GRINS::MeshManager class.
//
// $Id$
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "grins_mesh_manager.h"

#include <iostream>

GRINS::MeshManager::MeshManager()
  : _mesh(NULL),
    _mesh_built(false)
{
  return;
}

GRINS::MeshManager::~MeshManager()
{
  if( this->_mesh_built && this->_mesh )
    {
      delete _mesh;
    }
  return;
}

void GRINS::MeshManager::read_input_options( const GetPot& input )
{
  this->_mesh_option = (MESH_OPTION_ENUM)input("mesh-options/mesh_option",
                                               (int)READ_MESH_FROM_FILE);
  this->_print_mesh_info_flag = input("mesh-options/print_mesh_info_flag",
                                      false);

  if(this->_mesh_option==READ_MESH_FROM_FILE)
    {
      if(input.have_variable("mesh-options/mesh_filename"))
        {
          this->_mesh_filename = input("mesh-options/mesh_filename", "NULL");
        }
      else
        {
	  // TODO: Need more consistent error handling.
          std::cerr << " GRINS::MeshManager::read_input_options :" <<
                       " mesh-options/mesh_filename NOT specified " <<
                       std::endl;
          exit(1);
        }
    }
  else if(this->_mesh_option!=MESH_ALREADY_LOADED)
    {
      std::string domain_type_default_value;
      switch (this->_mesh_option)
      {
        case CREATE_1D_MESH:
          domain_type_default_value = "line";
          break;
        case CREATE_2D_MESH:
          domain_type_default_value = "rectangle";
          break;
        case CREATE_3D_MESH:
          domain_type_default_value = "box";
          break;
      }

      this->_domain_type = input("mesh-options/domain_type",
                                 domain_type_default_value);

      this->_domain_x1_min = input("mesh-options/domain_x1_min", 0.0);
      this->_domain_x2_min = input("mesh-options/domain_x2_min", 0.0);
      this->_domain_x3_min = input("mesh-options/domain_x3_min", 0.0);

      this->_domain_x1_max = input("mesh-options/domain_x1_max", 1.0);
      this->_domain_x2_max = input("mesh-options/domain_x2_max", 1.0);
      this->_domain_x3_max = input("mesh-options/domain_x3_max", 1.0);

      this->_mesh_nx1 = input("mesh-options/mesh_nx1", 100);
      this->_mesh_nx2 = input("mesh-options/mesh_nx2", 100);
      this->_mesh_nx3 = input("mesh-options/mesh_nx3", 100);

      // set default element type as libMeshEnums::INVALID_ELEM and
      // switch it to an appropriate one based on domain type
      this->_element_type =
             (libMeshEnums::ElemType)input("mesh-options/element_type",
                                           (int)libMeshEnums::INVALID_ELEM);
    }

  return;
}

libMesh::Mesh* GRINS::MeshManager::get_mesh()
{
  // mesh can be available due to either set_mesh() or build_mesh()
  if( !this->_mesh )
    {
      // TODO: Need more consistent error handling.
      std::cerr << " GRINS::MeshManager::get_mesh :"
		<< " mesh not yet constructed. "
		<< std::endl;
      exit(1);
    }
  return this->_mesh;
}

void GRINS::MeshManager::set_mesh( libMesh::Mesh* mesh )
{
  this->_mesh = mesh;
  this->_mesh_built = true;
  return;
}

void GRINS::MeshManager::build_mesh()
{

  if( this->_mesh_option==MESH_ALREADY_LOADED )
    {
      // TODO: Need more consistent error handling.
      std::cerr << " GRINS::MeshManager::build_mesh :" <<
                   " mesh already loaded " << std::endl;
      exit(1);
    }

  switch (this->_mesh_option)
  {
    case READ_MESH_FROM_FILE:
      {
        (this->_mesh)->read(this->_mesh_filename);
      }
      break;
    case CREATE_1D_MESH:
      {
        _mesh = new libMesh::Mesh(1);
        libMesh::Mesh mesh = *_mesh;

        if(this->_element_type==libMeshEnums::INVALID_ELEM)
	  {
	    this->_element_type = libMeshEnums::EDGE2;
	  }

        libMesh::MeshTools::Generation::build_line(mesh,
                                          this->_mesh_nx1,
                                          this->_domain_x1_min,
                                          this->_domain_x1_max,
                                          this->_element_type);
      }
      break;
    case CREATE_2D_MESH:
      {
        _mesh = new libMesh::Mesh(2);
        libMesh::Mesh mesh = *_mesh;

        if(this->_element_type==libMeshEnums::INVALID_ELEM)
	  {
	    this->_element_type = libMeshEnums::TRI3;
	  }

        libMesh::MeshTools::Generation::build_square(mesh,
                                          this->_mesh_nx1,
                                          this->_mesh_nx2,
                                          this->_domain_x1_min,
                                          this->_domain_x1_max,
                                          this->_domain_x2_min,
                                          this->_domain_x2_max,
                                          this->_element_type);
      }
      break;
    case CREATE_3D_MESH:
      {
        // TODO: fill
      }
      break;
    default:
      {
	// TODO: Need more consistent error handling.
        std::cerr << " GRINS::MeshManager::build_mesh :" <<
                     " specified mesh-options/mesh_option NOT supported " <<
                     std::endl;
        exit(1);
      }
      break;
  }

  this->_mesh_built = true;

  return;
}
<commit_msg>[grins/code/trunk]: newed mesh object in the case of READ_MESH_FROM_FILE. Related to #1360.<commit_after>//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//
// Copyright (C) 2008-2010 The PECOS Development Team
//
// Please see http://pecos.ices.utexas.edu for more information.
//
// This file is part of GRINS.
//
// GRINS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GRINS 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with GRINS.  If not, see <http://www.gnu.org/licenses/>.
//
//--------------------------------------------------------------------------
//
// Definitions for the GRINS::MeshManager class.
//
// $Id$
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

#include "grins_mesh_manager.h"

#include <iostream>

GRINS::MeshManager::MeshManager()
  : _mesh(NULL),
    _mesh_built(false)
{
  return;
}

GRINS::MeshManager::~MeshManager()
{
  if( this->_mesh_built && this->_mesh )
    {
      delete _mesh;
    }
  return;
}

void GRINS::MeshManager::read_input_options( const GetPot& input )
{
  this->_mesh_option = (MESH_OPTION_ENUM)input("mesh-options/mesh_option",
                                               (int)READ_MESH_FROM_FILE);
  this->_print_mesh_info_flag = input("mesh-options/print_mesh_info_flag",
                                      false);

  if(this->_mesh_option==READ_MESH_FROM_FILE)
    {
      if(input.have_variable("mesh-options/mesh_filename"))
        {
          this->_mesh_filename = input("mesh-options/mesh_filename", "NULL");
        }
      else
        {
	  // TODO: Need more consistent error handling.
          std::cerr << " GRINS::MeshManager::read_input_options :" <<
                       " mesh-options/mesh_filename NOT specified " <<
                       std::endl;
          exit(1);
        }
    }
  else if(this->_mesh_option!=MESH_ALREADY_LOADED)
    {
      std::string domain_type_default_value;
      switch (this->_mesh_option)
      {
        case CREATE_1D_MESH:
          domain_type_default_value = "line";
          break;
        case CREATE_2D_MESH:
          domain_type_default_value = "rectangle";
          break;
        case CREATE_3D_MESH:
          domain_type_default_value = "box";
          break;
      }

      this->_domain_type = input("mesh-options/domain_type",
                                 domain_type_default_value);

      this->_domain_x1_min = input("mesh-options/domain_x1_min", 0.0);
      this->_domain_x2_min = input("mesh-options/domain_x2_min", 0.0);
      this->_domain_x3_min = input("mesh-options/domain_x3_min", 0.0);

      this->_domain_x1_max = input("mesh-options/domain_x1_max", 1.0);
      this->_domain_x2_max = input("mesh-options/domain_x2_max", 1.0);
      this->_domain_x3_max = input("mesh-options/domain_x3_max", 1.0);

      this->_mesh_nx1 = input("mesh-options/mesh_nx1", 100);
      this->_mesh_nx2 = input("mesh-options/mesh_nx2", 100);
      this->_mesh_nx3 = input("mesh-options/mesh_nx3", 100);

      // set default element type as libMeshEnums::INVALID_ELEM and
      // switch it to an appropriate one based on domain type
      this->_element_type =
             (libMeshEnums::ElemType)input("mesh-options/element_type",
                                           (int)libMeshEnums::INVALID_ELEM);
    }

  return;
}

libMesh::Mesh* GRINS::MeshManager::get_mesh()
{
  // mesh can be available due to either set_mesh() or build_mesh()
  if( !this->_mesh )
    {
      // TODO: Need more consistent error handling.
      std::cerr << " GRINS::MeshManager::get_mesh :"
		<< " mesh not yet constructed. "
		<< std::endl;
      exit(1);
    }
  return this->_mesh;
}

void GRINS::MeshManager::set_mesh( libMesh::Mesh* mesh )
{
  this->_mesh = mesh;
  this->_mesh_built = true;
  return;
}

void GRINS::MeshManager::build_mesh()
{

  if( this->_mesh_option==MESH_ALREADY_LOADED )
    {
      // TODO: Need more consistent error handling.
      std::cerr << " GRINS::MeshManager::build_mesh :" <<
                   " mesh already loaded " << std::endl;
      exit(1);
    }

  switch (this->_mesh_option)
  {
    case READ_MESH_FROM_FILE:
      {
        _mesh = new libMesh::Mesh();
        (this->_mesh)->read(this->_mesh_filename);
      }
      break;
    case CREATE_1D_MESH:
      {
        _mesh = new libMesh::Mesh(1);
        libMesh::Mesh mesh = *_mesh;

        if(this->_element_type==libMeshEnums::INVALID_ELEM)
	  {
	    this->_element_type = libMeshEnums::EDGE2;
	  }

        libMesh::MeshTools::Generation::build_line(mesh,
                                          this->_mesh_nx1,
                                          this->_domain_x1_min,
                                          this->_domain_x1_max,
                                          this->_element_type);
      }
      break;
    case CREATE_2D_MESH:
      {
        _mesh = new libMesh::Mesh(2);
        libMesh::Mesh mesh = *_mesh;

        if(this->_element_type==libMeshEnums::INVALID_ELEM)
	  {
	    this->_element_type = libMeshEnums::TRI3;
	  }

        libMesh::MeshTools::Generation::build_square(mesh,
                                          this->_mesh_nx1,
                                          this->_mesh_nx2,
                                          this->_domain_x1_min,
                                          this->_domain_x1_max,
                                          this->_domain_x2_min,
                                          this->_domain_x2_max,
                                          this->_element_type);
      }
      break;
    case CREATE_3D_MESH:
      {
        // TODO: fill
      }
      break;
    default:
      {
	// TODO: Need more consistent error handling.
        std::cerr << " GRINS::MeshManager::build_mesh :" <<
                     " specified mesh-options/mesh_option NOT supported " <<
                     std::endl;
        exit(1);
      }
      break;
  }

  this->_mesh_built = true;

  return;
}
<|endoftext|>


<commit_before>// This file is part of FTE.
//
// FTE is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// FTE 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FTE.  If not, see <http://www.gnu.org/licenses/>.

#include <cDFA.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/algorithm/string.hpp>

#include "util/test.h"
#include "util/thread.h"
#include "re2/prog.h"
#include "re2/re2.h"
#include "re2/regexp.h"
#include "re2/testing/regexp_generator.h"
#include "re2/testing/string_generator.h"

DFA::DFA(std::string DFA, uint32_t MAX_WORD_LEN)
    : _max_len(MAX_WORD_LEN),
      _start_state(-1)
{
    std::vector<uint32_t> symbolsTmp;
    boost::unordered_set<uint32_t> statesTmp;
    boost::unordered_set<uint32_t> final_statesTmp;

    std::string line;
    std::istringstream myfile(DFA);
    while ( getline (myfile,line) )
    {
        if (line.empty()) break;

        typedef vector< std::string > split_vector_type;
        split_vector_type SplitVec;
        boost::split( SplitVec, line, boost::is_any_of("\t") );
        std::string bits = SplitVec[SplitVec.size()-1];

        if (SplitVec.size() == 4 || SplitVec.size()==5) {
            uint32_t current_state = strtol(SplitVec[0].c_str(),NULL,10);
            uint32_t symbol = strtol(SplitVec[2].c_str(),NULL,10);
            if (statesTmp.count(current_state)==0) {
                statesTmp.insert( current_state );
            }

            if (find(symbolsTmp.begin(), symbolsTmp.end(), symbol)==symbolsTmp.end()) {
                symbolsTmp.push_back( symbol );
            }

            if (_start_state==-1) {
                _start_state = current_state;
            }
        } else if (SplitVec.size()==1 || SplitVec.size()==2) {
            uint32_t final_state = strtol(SplitVec[0].c_str(),NULL,10);
            if (statesTmp.count(final_state)==0) {
                statesTmp.insert( final_state );
            }
            final_statesTmp.insert( final_state );
        }
    }

    _final_states = final_statesTmp;

    statesTmp.insert( statesTmp.size() );

    uint32_t j, k;

    const uint32_t NUM_STATES = statesTmp.size();
    const uint32_t NUM_SYMBOLS = symbolsTmp.size();

    statesTmp.clear();
    final_statesTmp.clear();

    array_type_uint32_t2 deltaTmp(boost::extents[NUM_STATES][NUM_SYMBOLS]);

    std::map<uint32_t, char> sigmaTmp;
    std::map<char,uint32_t> sigmaReverseTmp;
    for (j=0; j<NUM_SYMBOLS; j++) {
        sigmaTmp[j] = (char)(symbolsTmp[j]-1);
        sigmaReverseTmp[(char)(symbolsTmp[j]-1)] = j;
    }
    _sigma = sigmaTmp;
    _sigma_reverse = sigmaReverseTmp;

    for (j=0; j<NUM_STATES; j++) {
        for (k=0; k<NUM_SYMBOLS; k++) {
            deltaTmp[j][k] = NUM_STATES-1;
        }
    }

    std::istringstream myfile2(DFA);
    typedef std::vector< std::string > split_vector_type;

    while ( getline (myfile2,line) )
    {
        split_vector_type SplitVec;
        boost::split( SplitVec, line, boost::is_any_of("\t") );
        std::string bits = SplitVec[SplitVec.size()-1];

        if (SplitVec.size() > 2) {
            uint32_t current_state = strtol(SplitVec[0].c_str(),NULL,10);
            uint32_t symbol = strtol(SplitVec[2].c_str(),NULL,10);

            uint32_t i;
            for (i=0; i<symbolsTmp.size(); i++) {
                if(symbolsTmp[i]==symbol) {
                    symbol = i;
                    break;
                }
            }

            uint32_t new_state = strtol(SplitVec[1].c_str(),NULL,10);

            deltaTmp[current_state][symbol] = new_state;
        }
    }

    _delta.resize(boost::extents[NUM_STATES][NUM_SYMBOLS]);
    _delta = deltaTmp;

    array_type_mpz_t2 TTmp(boost::extents[NUM_STATES][MAX_WORD_LEN+1]);
    _T.resize(boost::extents[NUM_STATES][MAX_WORD_LEN+1]);
    DFA::buildTable();
}

void DFA::buildTable() {
    uint32_t i, q, a;
    uint32_t n = _max_len;

    boost::unordered_set<uint32_t>::iterator it;
    for (it=_final_states.begin(); it!=_final_states.end(); it++) {
        _T[*it][0] = 1;
    }

    mpz_t tmp;
    mpz_init(tmp);
    for (i=1; i<=n; i++) {
        for (q=0; q<_delta.size(); q++) {
            for (a=0; a<_delta[0].size(); a++) {
                if ( mpz_cmp_ui( _T[_delta[q][a]][i-1].get_mpz_t(), 0 ) > 0 )
                    _T[q][i] += _T[_delta[q][a]][i-1];
            }
        }
    }
    mpz_clear(tmp);

}

std::string DFA::unrank(PyObject * c_input ) {
    array_type_uint32_t1 Xtmp;

    mpz_t c;
    mpz_init_set(c, Pympz_AS_MPZ(c_input));
    //DFA::doUnrank(tmp, Pympz_AS_MPZ(c) );

    /////////////////////
    uint32_t q = _start_state;
    uint32_t n = 1;
    uint32_t i;
    uint32_t idx;
    const uint32_t *j;
    mpz_t cTmp;
    mpz_t jTmp;

    mpz_init(jTmp);
    mpz_init_set(cTmp,c);

    while ( mpz_cmp(cTmp, _T[_start_state][n].get_mpz_t()) >= 0 ) {
        mpz_sub( cTmp, cTmp, _T[_start_state][n].get_mpz_t() );
        n++;
    }

    Xtmp.resize(boost::extents[n]);

    for (i=1; i<=n; i++) {
        idx = n-i;
        j = &_delta[q][0];
        while (mpz_cmp( cTmp, _T[*j][idx].get_mpz_t() ) >= 0) {
            mpz_sub( cTmp, cTmp, _T[*j][idx].get_mpz_t() );
            j += 1;
        }
        Xtmp[i-1] = j - &_delta[q][0];
        q = *j;
    }

    mpz_clear(cTmp);
    mpz_clear(jTmp);

    if (_final_states.count(q)==0) {
        Xtmp.resize(boost::extents[0]);
        return NULL;
    }
    /////////////////////

    //uint32_t i;
    std::string X;
    for (i=0; i<Xtmp.size(); i++) {
        X += _sigma[Xtmp[i]];
    }

    return X;
}

PyObject* DFA::rank( std::string X_input ) {
    uint32_t i;
    mpz_t c;
    uint32_t q = _start_state;
    uint32_t j;
    array_type_uint32_t1 X(boost::extents[X_input.size()]);
    mpz_t tmp;

    for (i=0; i<X_input.size(); i++) {
        X[i] = _sigma_reverse[X_input.at(i)];
    }

    uint32_t n = X.size();
    mpz_init(c);

    /////////////////////////////
    if (_T[0].size() < X.size()) {
        mpz_set_si( c, -1 );
        return NULL;
    }

    mpz_init(tmp);

    mpz_init_set_si( c, 0 );

    for (i=1; i<=n; i++) {
        for (j=1; j<=X[i-1]; j++) {
            mpz_add( c, c, _T[_delta[q][j-1]][n-i].get_mpz_t() );
        }
        q = _delta[q][X[i-1]];

        if (q == (_delta.size()-1)) {
            mpz_set_si( c, -1 );
            return NULL;
        }
    }

    mpz_clear(tmp);

    if (_final_states.count(q)==0) {
        mpz_set_si( c, -1 );
        return NULL;
    }

    for (i=0; i<n; i++)
        mpz_add( c, c, _T[_start_state][i].get_mpz_t() );
    /////////////////////////////

    char * retval_str = mpz_get_str(NULL, 10, c);

    return PyLong_FromString(retval_str,NULL,10);
}

PyObject* DFA::getNumWordsInLanguage( uint32_t min_word_length,
									  uint32_t max_word_length )
{
	PyObject* retval;

	// count the number of words in the language of length
	// at least min_word_length and no greater than max_word_length
    mpz_class num_words = 0;
    for (uint32_t word_length = min_word_length;
    	 word_length<= max_word_length;
    	 word_length++) {
    	num_words += _T[_start_state][word_length];
    }

    // convert the resulting integer to a string
    uint8_t base = 10;
    char *num_words_str = new char[num_words.get_str().length() + 1];
    strcpy(num_words_str, num_words.get_str().c_str());
    retval = PyLong_FromString(num_words_str, NULL, base);

    // cleanup
    delete [] num_words_str;

    return retval;
}

std::string attFstFromRegex(std::string regex)
{
	std::string retval;

	// specify compile flags for re2
    re2::Regexp::ParseFlags re_flags;
    re_flags = re2::Regexp::ClassNL;
    re_flags = re_flags | re2::Regexp::OneLine;
    re_flags = re_flags | re2::Regexp::PerlClasses;
    re_flags = re_flags | re2::Regexp::PerlB;
    re_flags = re_flags | re2::Regexp::PerlX;
	re_flags = re_flags | re2::Regexp::Latin1;

	// compile regex to DFA
	RE2::Options opt;
    re2::Regexp* re = re2::Regexp::Parse( regex, re_flags, NULL );
    re2::Prog* prog = re->CompileToProg( opt.max_mem() );
    retval = prog->PrintEntireDFA( re2::Prog::kFullMatch );

    // cleanup
    delete prog;
    re->Decref();

    return retval;
}

std::string attFstMinimize(std::string str_dfa)
{
	std::string retval;

	// create the destinations for our working files
	boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
    boost::filesystem::path temp_file = boost::filesystem::unique_path();

    std::string abspath_dfa     = temp_dir.native() + "/" + temp_file.native() + ".dfa";
    std::string abspath_fst     = temp_dir.native() + "/" + temp_file.native() + ".fst";
    std::string abspath_fst_min = temp_dir.native() + "/" + temp_file.native() + ".min.fst";
    std::string abspath_dfa_min = temp_dir.native() + "/" + temp_file.native() + ".min.dfa";

    // write our input DFA to disk
    std::ofstream dfa_stream;
    dfa_stream.open (abspath_dfa.c_str());
    dfa_stream << str_dfa;
    dfa_stream.close();

    std::string cmd;
    // convert our ATT DFA string to an FST
    cmd = "fstcompile " + abspath_dfa + " " + abspath_fst;
    system(cmd.c_str());

    // convert our FST to a minmized FST
    cmd = "fstminimize " + abspath_fst + " " + abspath_fst_min;
    system(cmd.c_str());

    // covert our minimized FST to an ATT FST string
    cmd = "fstprint " + abspath_fst_min + " " + abspath_dfa_min;
    system(cmd.c_str());

    // read the contents of of the file at abspath_dfa_min to our retval
    std::ifstream dfa_min_stream(abspath_dfa_min.c_str());
    std::stringstream buffer;
    buffer << dfa_min_stream.rdbuf();
    retval = std::string(buffer.str());
    dfa_min_stream.close();

    // cleanup
    remove( abspath_dfa.c_str() );
    remove( abspath_fst.c_str() );
    remove( abspath_fst_min.c_str() );
    remove( abspath_dfa_min.c_str() );

    return retval;
}

BOOST_PYTHON_MODULE(cDFA)
{
    boost::python::class_<DFA>("DFA",boost::python::init<std::string,int32_t>())
    .def("rank", &DFA::rank)
    .def("unrank", &DFA::unrank)
    .def("getNumWordsInLanguage", &DFA::getNumWordsInLanguage);

    boost::python::def("attFstFromRegex",attFstFromRegex);
    boost::python::def("attFstMinimize",attFstMinimize);
}
<commit_msg>Issue #29: Formatting fix<commit_after>// This file is part of FTE.
//
// FTE is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// FTE 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FTE.  If not, see <http://www.gnu.org/licenses/>.

#include <cDFA.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/class.hpp>
#include <boost/algorithm/string.hpp>

#include "util/test.h"
#include "util/thread.h"
#include "re2/prog.h"
#include "re2/re2.h"
#include "re2/regexp.h"
#include "re2/testing/regexp_generator.h"
#include "re2/testing/string_generator.h"

DFA::DFA(std::string DFA, uint32_t MAX_WORD_LEN)
    : _max_len(MAX_WORD_LEN),
      _start_state(-1)
{
    std::vector<uint32_t> symbolsTmp;
    boost::unordered_set<uint32_t> statesTmp;
    boost::unordered_set<uint32_t> final_statesTmp;

    std::string line;
    std::istringstream myfile(DFA);
    while ( getline (myfile,line) )
    {
        if (line.empty()) break;

        typedef vector< std::string > split_vector_type;
        split_vector_type SplitVec;
        boost::split( SplitVec, line, boost::is_any_of("\t") );
        std::string bits = SplitVec[SplitVec.size()-1];

        if (SplitVec.size() == 4 || SplitVec.size()==5) {
            uint32_t current_state = strtol(SplitVec[0].c_str(),NULL,10);
            uint32_t symbol = strtol(SplitVec[2].c_str(),NULL,10);
            if (statesTmp.count(current_state)==0) {
                statesTmp.insert( current_state );
            }

            if (find(symbolsTmp.begin(), symbolsTmp.end(), symbol)==symbolsTmp.end()) {
                symbolsTmp.push_back( symbol );
            }

            if (_start_state==-1) {
                _start_state = current_state;
            }
        } else if (SplitVec.size()==1 || SplitVec.size()==2) {
            uint32_t final_state = strtol(SplitVec[0].c_str(),NULL,10);
            if (statesTmp.count(final_state)==0) {
                statesTmp.insert( final_state );
            }
            final_statesTmp.insert( final_state );
        }
    }

    _final_states = final_statesTmp;

    statesTmp.insert( statesTmp.size() );

    uint32_t j, k;

    const uint32_t NUM_STATES = statesTmp.size();
    const uint32_t NUM_SYMBOLS = symbolsTmp.size();

    statesTmp.clear();
    final_statesTmp.clear();

    array_type_uint32_t2 deltaTmp(boost::extents[NUM_STATES][NUM_SYMBOLS]);

    std::map<uint32_t, char> sigmaTmp;
    std::map<char,uint32_t> sigmaReverseTmp;
    for (j=0; j<NUM_SYMBOLS; j++) {
        sigmaTmp[j] = (char)(symbolsTmp[j]-1);
        sigmaReverseTmp[(char)(symbolsTmp[j]-1)] = j;
    }
    _sigma = sigmaTmp;
    _sigma_reverse = sigmaReverseTmp;

    for (j=0; j<NUM_STATES; j++) {
        for (k=0; k<NUM_SYMBOLS; k++) {
            deltaTmp[j][k] = NUM_STATES-1;
        }
    }

    std::istringstream myfile2(DFA);
    typedef std::vector< std::string > split_vector_type;

    while ( getline (myfile2,line) )
    {
        split_vector_type SplitVec;
        boost::split( SplitVec, line, boost::is_any_of("\t") );
        std::string bits = SplitVec[SplitVec.size()-1];

        if (SplitVec.size() > 2) {
            uint32_t current_state = strtol(SplitVec[0].c_str(),NULL,10);
            uint32_t symbol = strtol(SplitVec[2].c_str(),NULL,10);

            uint32_t i;
            for (i=0; i<symbolsTmp.size(); i++) {
                if(symbolsTmp[i]==symbol) {
                    symbol = i;
                    break;
                }
            }

            uint32_t new_state = strtol(SplitVec[1].c_str(),NULL,10);

            deltaTmp[current_state][symbol] = new_state;
        }
    }

    _delta.resize(boost::extents[NUM_STATES][NUM_SYMBOLS]);
    _delta = deltaTmp;

    array_type_mpz_t2 TTmp(boost::extents[NUM_STATES][MAX_WORD_LEN+1]);
    _T.resize(boost::extents[NUM_STATES][MAX_WORD_LEN+1]);
    DFA::buildTable();
}

void DFA::buildTable() {
    uint32_t i, q, a;
    uint32_t n = _max_len;

    boost::unordered_set<uint32_t>::iterator it;
    for (it=_final_states.begin(); it!=_final_states.end(); it++) {
        _T[*it][0] = 1;
    }

    mpz_t tmp;
    mpz_init(tmp);
    for (i=1; i<=n; i++) {
        for (q=0; q<_delta.size(); q++) {
            for (a=0; a<_delta[0].size(); a++) {
                if ( mpz_cmp_ui( _T[_delta[q][a]][i-1].get_mpz_t(), 0 ) > 0 )
                    _T[q][i] += _T[_delta[q][a]][i-1];
            }
        }
    }
    mpz_clear(tmp);

}

std::string DFA::unrank(PyObject * c_input ) {
    array_type_uint32_t1 Xtmp;

    mpz_t c;
    mpz_init_set(c, Pympz_AS_MPZ(c_input));
    //DFA::doUnrank(tmp, Pympz_AS_MPZ(c) );

    /////////////////////
    uint32_t q = _start_state;
    uint32_t n = 1;
    uint32_t i;
    uint32_t idx;
    const uint32_t *j;
    mpz_t cTmp;
    mpz_t jTmp;

    mpz_init(jTmp);
    mpz_init_set(cTmp,c);

    while ( mpz_cmp(cTmp, _T[_start_state][n].get_mpz_t()) >= 0 ) {
        mpz_sub( cTmp, cTmp, _T[_start_state][n].get_mpz_t() );
        n++;
    }

    Xtmp.resize(boost::extents[n]);

    for (i=1; i<=n; i++) {
        idx = n-i;
        j = &_delta[q][0];
        while (mpz_cmp( cTmp, _T[*j][idx].get_mpz_t() ) >= 0) {
            mpz_sub( cTmp, cTmp, _T[*j][idx].get_mpz_t() );
            j += 1;
        }
        Xtmp[i-1] = j - &_delta[q][0];
        q = *j;
    }

    mpz_clear(cTmp);
    mpz_clear(jTmp);

    if (_final_states.count(q)==0) {
        Xtmp.resize(boost::extents[0]);
        return NULL;
    }
    /////////////////////

    //uint32_t i;
    std::string X;
    for (i=0; i<Xtmp.size(); i++) {
        X += _sigma[Xtmp[i]];
    }

    return X;
}

PyObject* DFA::rank( std::string X_input ) {
    uint32_t i;
    mpz_t c;
    uint32_t q = _start_state;
    uint32_t j;
    array_type_uint32_t1 X(boost::extents[X_input.size()]);
    mpz_t tmp;

    for (i=0; i<X_input.size(); i++) {
        X[i] = _sigma_reverse[X_input.at(i)];
    }

    uint32_t n = X.size();
    mpz_init(c);

    /////////////////////////////
    if (_T[0].size() < X.size()) {
        mpz_set_si( c, -1 );
        return NULL;
    }

    mpz_init(tmp);

    mpz_init_set_si( c, 0 );

    for (i=1; i<=n; i++) {
        for (j=1; j<=X[i-1]; j++) {
            mpz_add( c, c, _T[_delta[q][j-1]][n-i].get_mpz_t() );
        }
        q = _delta[q][X[i-1]];

        if (q == (_delta.size()-1)) {
            mpz_set_si( c, -1 );
            return NULL;
        }
    }

    mpz_clear(tmp);

    if (_final_states.count(q)==0) {
        mpz_set_si( c, -1 );
        return NULL;
    }

    for (i=0; i<n; i++)
        mpz_add( c, c, _T[_start_state][i].get_mpz_t() );
    /////////////////////////////

    char * retval_str = mpz_get_str(NULL, 10, c);

    return PyLong_FromString(retval_str,NULL,10);
}

PyObject* DFA::getNumWordsInLanguage( uint32_t min_word_length,
                                      uint32_t max_word_length )
{
    PyObject* retval;

    // count the number of words in the language of length
    // at least min_word_length and no greater than max_word_length
    mpz_class num_words = 0;
    for (uint32_t word_length = min_word_length;
            word_length<= max_word_length;
            word_length++) {
        num_words += _T[_start_state][word_length];
    }

    // convert the resulting integer to a string
    uint8_t base = 10;
    char *num_words_str = new char[num_words.get_str().length() + 1];
    strcpy(num_words_str, num_words.get_str().c_str());
    retval = PyLong_FromString(num_words_str, NULL, base);

    // cleanup
    delete [] num_words_str;

    return retval;
}

std::string attFstFromRegex(std::string regex)
{
    std::string retval;

    // specify compile flags for re2
    re2::Regexp::ParseFlags re_flags;
    re_flags = re2::Regexp::ClassNL;
    re_flags = re_flags | re2::Regexp::OneLine;
    re_flags = re_flags | re2::Regexp::PerlClasses;
    re_flags = re_flags | re2::Regexp::PerlB;
    re_flags = re_flags | re2::Regexp::PerlX;
    re_flags = re_flags | re2::Regexp::Latin1;

    // compile regex to DFA
    RE2::Options opt;
    re2::Regexp* re = re2::Regexp::Parse( regex, re_flags, NULL );
    re2::Prog* prog = re->CompileToProg( opt.max_mem() );
    retval = prog->PrintEntireDFA( re2::Prog::kFullMatch );

    // cleanup
    delete prog;
    re->Decref();

    return retval;
}

std::string attFstMinimize(std::string str_dfa)
{
    std::string retval;

    // create the destinations for our working files
    boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
    boost::filesystem::path temp_file = boost::filesystem::unique_path();

    std::string abspath_dfa     = temp_dir.native() + "/" + temp_file.native() + ".dfa";
    std::string abspath_fst     = temp_dir.native() + "/" + temp_file.native() + ".fst";
    std::string abspath_fst_min = temp_dir.native() + "/" + temp_file.native() + ".min.fst";
    std::string abspath_dfa_min = temp_dir.native() + "/" + temp_file.native() + ".min.dfa";

    // write our input DFA to disk
    std::ofstream dfa_stream;
    dfa_stream.open (abspath_dfa.c_str());
    dfa_stream << str_dfa;
    dfa_stream.close();

    std::string cmd;
    // convert our ATT DFA string to an FST
    cmd = "fstcompile " + abspath_dfa + " " + abspath_fst;
    system(cmd.c_str());

    // convert our FST to a minmized FST
    cmd = "fstminimize " + abspath_fst + " " + abspath_fst_min;
    system(cmd.c_str());

    // covert our minimized FST to an ATT FST string
    cmd = "fstprint " + abspath_fst_min + " " + abspath_dfa_min;
    system(cmd.c_str());

    // read the contents of of the file at abspath_dfa_min to our retval
    std::ifstream dfa_min_stream(abspath_dfa_min.c_str());
    std::stringstream buffer;
    buffer << dfa_min_stream.rdbuf();
    retval = std::string(buffer.str());
    dfa_min_stream.close();

    // cleanup
    remove( abspath_dfa.c_str() );
    remove( abspath_fst.c_str() );
    remove( abspath_fst_min.c_str() );
    remove( abspath_dfa_min.c_str() );

    return retval;
}

BOOST_PYTHON_MODULE(cDFA)
{
    boost::python::class_<DFA>("DFA",boost::python::init<std::string,int32_t>())
    .def("rank", &DFA::rank)
    .def("unrank", &DFA::unrank)
    .def("getNumWordsInLanguage", &DFA::getNumWordsInLanguage);

    boost::python::def("attFstFromRegex",attFstFromRegex);
    boost::python::def("attFstMinimize",attFstMinimize);
}
<|endoftext|>


<commit_before>// Constants.hpp - Header file containing important constants for the library
#ifndef CONSTANTS_H
#define CONSTANTS_H

namespace Constants
{
  const float KB = 1.3806485e-23;
  const float GYROMAG = 1.76086e11;
}

#endif
<commit_msg>added mu0 to constants<commit_after>// Constants.hpp - Header file containing important constants for the library
#ifndef CONSTANTS_H
#define CONSTANTS_H

namespace Constants
{
  const float KB = 1.3806485e-23;
  const float GYROMAG = 1.76086e11;
  const float MU0 = 1.256637e-6;
}

#endif
<|endoftext|>


<commit_before>//
// Created by peixot_b on 12/06/17.
//

#include <thread>
#include <iostream>
#include "Camera.hpp"
#include "map.hpp"
#include "IGameState.hpp"

Camera::Camera(irr::scene::ISceneManager* smgr, irr::video::IVideoDriver *driver,
	       CamMode cameraMode, is::GameEngine *engine)
	: _smgr(smgr), _driver(driver), _currMode(cameraMode), _engine(engine), _anim(0),
	  _anim1Time(10000), _anim2Time(5000), _anim3Time(5000), _anim4Time(5000)
{
  _timer = _engine->getDevice()->getTimer();
}

Camera::~Camera()
{

}

void			Camera::setMenuMode()
{
  irr::scene::ISceneNodeAnimator* anim = 0;
  //setTextMenu();
  anim = _smgr->createFlyCircleAnimator(irr::core::vector3df(0,200,0), 400.0f, 0.0003f);
  _smgr->addCameraSceneNode(0, irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100),
			   irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2,
						0.0f,
						((0.5 + (BLOCK - 1)) * SCALE)) / 2)->addAnimator(anim);
  //anim = _smgr->createFlyCircleAnimator(irr::core::vector3df(0,200,0), 300.0f, 0.0009f);
  //_node->addAnimator(anim);
  anim->drop();
}

void			Camera::setInGameMode()
{
  _smgr->addCameraSceneNode(0, irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2, 180, -80),
			    irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2,
						 0.0f,
						 ((0.5 + (BLOCK - 1)) * SCALE) / 2));
}

void Camera::setAnimation1()
{
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(0, 3 * SCALE, -2750),
					  irr::core::vector3df(0, 3 * SCALE, 100),
					  _anim1Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setAnimation2()
{
  _node->setVisible(0);
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(0, 3 * SCALE, 100),
					   irr::core::vector3df(((0.4 + (BLOCK - 2)) * SCALE),
								1000,
								((0.4 + (BLOCK)) * SCALE)),
					   _anim2Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setAnimation3()
{
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(((0.4 + (BLOCK - 2)) * SCALE),
								1000,
								((0.4 + (BLOCK)) * SCALE)),
					   irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE),
								100,
								((0.5 + (BLOCK)) * SCALE)),
					   _anim3Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setTextMenu()
{
  _mesh = _smgr->getMesh("./gfx/bomberman3D.obj");
  _node = _smgr->addAnimatedMeshSceneNode(_mesh);
  if (_node)
    {
      _node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      _node->setMD2Animation(scene::EMAT_STAND);
      _node->setScale({10.0f, 10.0f, 10.0f});
      _node->setRotation({0, 180, 0});
      _node->setMaterialTexture( 0, _driver->getTexture("./gfx/fire.jpg"));
      _node->setPosition(irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100));
    }
  _node->setVisible(1);
}

void Camera::draw()
{
  _camera->render();
  _node->render();
}

void Camera::setTextIntro()
{
  _mesh = _smgr->getMesh("./gfx/indiestudio2.obj");
  _node = _smgr->addAnimatedMeshSceneNode(_mesh);
  if (_node)
    {
      _node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      _node->setMD2Animation(scene::EMAT_STAND);
      _node->setScale({10.0f, 10.0f, 10.0f});
      _node->setRotation({0, 180, 0});
      _node->setMaterialTexture( 0, _driver->getTexture("./gfx/fire.jpg"));
      _node->setPosition({-14, 3 * SCALE - 5, -1600});
    }
}

void			Camera::setSplashScreen()
{
  _camera = _smgr->addCameraSceneNode(0,
				     irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100),
				     irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2,
							  0.0,
							  ((0.5 + (BLOCK)) * SCALE) / 2));
  setTextIntro();
  setAnimation1();
  while (_engine->Running())
    {
      if (_timer->getTime() >= _anim1Time - 30 && _timer->getTime() <= (_anim1Time))
	setAnimation2();
      if (_timer->getTime() >= (_anim1Time + _anim2Time - 30) && _timer->getTime() <= (_anim1Time + _anim2Time))
	setAnimation3();
      _engine->HandleEvents();
      _engine->Update();
      _engine->Draw();
      if (_timer->getTime() >= (_anim1Time + _anim2Time + _anim3Time) - 30)
	{
	  setMenuMode();
	  break;
	}
    }
  _anim->drop();
}

scene::ISceneManager	*Camera::get_smgr() const
{
  return _smgr;
}

CamMode			Camera::get_currMode() const
{
  return _currMode;
}

void			Camera::set_smgr(scene::ISceneManager *_smgr)
{
  Camera::_smgr = _smgr;
}

void			Camera::set_currMode(CamMode _currMode)
{
  Camera::_currMode = _currMode;
}
<commit_msg>Modif camera<commit_after>//
// Created by peixot_b on 12/06/17.
//

#include <thread>
#include <iostream>
#include "Camera.hpp"
#include "map.hpp"
#include "IGameState.hpp"

Camera::Camera(irr::scene::ISceneManager* smgr, irr::video::IVideoDriver *driver,
	       CamMode cameraMode, is::GameEngine *engine)
	: _smgr(smgr), _driver(driver), _currMode(cameraMode), _engine(engine), _anim(0),
	  _anim1Time(10000), _anim2Time(5000), _anim3Time(5000), _anim4Time(5000)
{
  _timer = _engine->getDevice()->getTimer();
}

Camera::~Camera()
{

}

void			Camera::setMenuMode()
{
  irr::scene::ISceneNodeAnimator* anim = 0;
  //setTextMenu();
  anim = _smgr->createFlyCircleAnimator(irr::core::vector3df(0,200,0), 400.0f, 0.0003f);
  _smgr->addCameraSceneNode(0, irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100),
			   irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2,
						0.0f,
						((0.5 + (BLOCK - 1)) * SCALE)) / 2)->addAnimator(anim);
  //anim = _smgr->createFlyCircleAnimator(irr::core::vector3df(0,200,0), 300.0f, 0.0009f);
  //_node->addAnimator(anim);
  anim->drop();
}

void			Camera::setInGameMode()
{
  _smgr->addCameraSceneNode(0, irr::core::vector3df((((0.5 + (BLOCK - 2)) * SCALE) / 2) - 2, 150, 30),
			    irr::core::vector3df((((0.5 + (BLOCK - 2)) * SCALE) / 2) - 2,
						 0,
						 (((0.5 + (BLOCK - 1)) * SCALE) / 2)));
}

void Camera::setAnimation1()
{
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(0, 3 * SCALE, -2750),
					  irr::core::vector3df(0, 3 * SCALE, 100),
					  _anim1Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setAnimation2()
{
  _node->setVisible(0);
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(0, 3 * SCALE, 100),
					   irr::core::vector3df(((0.4 + (BLOCK - 2)) * SCALE),
								1000,
								((0.4 + (BLOCK)) * SCALE)),
					   _anim2Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setAnimation3()
{
  _anim = _smgr->createFlyStraightAnimator(irr::core::vector3df(((0.4 + (BLOCK - 2)) * SCALE),
								1000,
								((0.4 + (BLOCK)) * SCALE)),
					   irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE),
								100,
								((0.5 + (BLOCK)) * SCALE)),
					   _anim3Time, false, false);
  _camera->addAnimator(_anim);
}

void Camera::setTextMenu()
{
  _mesh = _smgr->getMesh("./gfx/bomberman3D.obj");
  _node = _smgr->addAnimatedMeshSceneNode(_mesh);
  if (_node)
    {
      _node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      _node->setMD2Animation(scene::EMAT_STAND);
      _node->setScale({10.0f, 10.0f, 10.0f});
      _node->setRotation({0, 180, 0});
      _node->setMaterialTexture( 0, _driver->getTexture("./gfx/fire.jpg"));
      _node->setPosition(irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100));
    }
  _node->setVisible(1);
}

void Camera::draw()
{
  _camera->render();
  _node->render();
}

void Camera::setTextIntro()
{
  _mesh = _smgr->getMesh("./gfx/indiestudio2.obj");
  _node = _smgr->addAnimatedMeshSceneNode(_mesh);
  if (_node)
    {
      _node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      _node->setMD2Animation(scene::EMAT_STAND);
      _node->setScale({10.0f, 10.0f, 10.0f});
      _node->setRotation({0, 180, 0});
      _node->setMaterialTexture( 0, _driver->getTexture("./gfx/fire.jpg"));
      _node->setPosition({-14, 3 * SCALE - 5, -1600});
    }
}

void			Camera::setSplashScreen()
{
  _camera = _smgr->addCameraSceneNode(0,
				     irr::core::vector3df(BLOCK / 2 * SCALE, 2000, BLOCK / 2 * 100),
				     irr::core::vector3df(((0.5 + (BLOCK - 2)) * SCALE) / 2,
							  0.0,
							  ((0.5 + (BLOCK)) * SCALE) / 2));
  setTextIntro();
  setAnimation1();
  while (_engine->Running())
    {
      if (_timer->getTime() >= _anim1Time - 30 && _timer->getTime() <= (_anim1Time))
	setAnimation2();
      if (_timer->getTime() >= (_anim1Time + _anim2Time - 30) && _timer->getTime() <= (_anim1Time + _anim2Time))
	setAnimation3();
      _engine->HandleEvents();
      _engine->Update();
      _engine->Draw();
      if (_timer->getTime() >= (_anim1Time + _anim2Time + _anim3Time) - 30)
	{
	  setMenuMode();
	  break;
	}
    }
  _anim->drop();
}

scene::ISceneManager	*Camera::get_smgr() const
{
  return _smgr;
}

CamMode			Camera::get_currMode() const
{
  return _currMode;
}

void			Camera::set_smgr(scene::ISceneManager *_smgr)
{
  Camera::_smgr = _smgr;
}

void			Camera::set_currMode(CamMode _currMode)
{
  Camera::_currMode = _currMode;
}
<|endoftext|>


<commit_before>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2016-01-20
 *
 * This C++ header file contains the implementation of the Labyrinth class,
 * which uses the Room class to create a 2-d mapping for a game.
 *
 */

#pragma once

#include <memory>

#include "room_properties.hpp"
#include "room.hpp"
#include "coordinate.hpp"

// Rooms are indexed first with the y-coordinate, then with the x-coordinate.
class Labyrinth
{
  public:

    // The Coordinates of a Labyrinth begin at (0, 0) at the top left, and
    // end at (x_size-1, y_size-1) at the bottom right.

    // CONSTRUCTOR/DESTRUCTOR:

      // Parameterized constructor
      // An exception is thrown if:
      //   A size of 0 is given (domain_error)
      //   An x or y size greater than the maximum is given (domain_error)
      Labyrinth( const size_t x_size, const size_t y_size );

    // SETUP:

      // This method connects two Rooms by breaking their walls.
      // An exception is thrown if:
      //   The Rooms are already connected (logic_error)
      //   The Rooms are the same (logic_error)
      //   The Rooms are not adjacent (logic_error)
      //   One or both Rooms are outside the Labyrinth (domain_error)
      void ConnectRooms( const Coordinate rm_1, const Coordinate rm_2 );

      // This method sets the primary (initial) spawn Room.
      //   The Room is outside the Labyrinth (domain_error)
      void SetSpawn1( const Coordinate rm );

      // This method sets the secondary spawn Room.
      //   The Room is outside the Labyrinth (domain_error)
      void SetSpawn2( const Coordinate rm );

      // This method sets the exit of the Labyrinth on a Wall.
      // An exception is thrown if:
      //   The Direction has another Room (invalid_argument)
      //   The Exit has already been set (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void SetExit( const Coordinate rm, const Direction d );

      // This method places the Labyrinth treasure in a Room.
      // May be used to drop the Treasure if a Player is dead.
      // An exception is thrown if:
      //   The Treasure has already been placed in another Room (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void SetTreasure( const Coordinate rm );

      // This method places an Inhabitant in a Room.
      // Cannot change an existing Inhabitant; use the EnemyAttacked() method
      // for that.
      // An exception is thrown if:
      //   The Inhabitant of the Room has already been set (logic_error)
      //   Inhabitant inh is a null Inhabitant (i.e. Inhabitant::kNone)
      //     (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      void SetInhabitant( const Coordinate rm, const Inhabitant inh );

      // This method places an Item in a Room.
      // Cannot change an existing Item; use the TakeItem() method for that.
      // An exception is thrown if:
      //   The Item of the Room has already been set (logic_error)
      //   Item itm is a null Item (i.e. Item::kNone) (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      void SetItem( Coordinate rm, Item itm );

    // PLAY:

      // This method returns the current Inhabitant of the Room.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      Inhabitant GetInhabitant( const Coordinate rm ) const;

      // This method attacks the Inhabitant of the Room, and sets the resultant
      // Inhabitant.
      // The bullet is not removed from the Player.
      // True is returned if:
      //   The Inhabitant was a Minotaur
      // False is returned if:
      //   The Inhabitant was a Mirror
      // An exception is thrown if:
      //   There is no enemy to attack (i.e. Inhabitant::kNone, dead Minotaur,
      //     or cracked Mirror) (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      bool EnemyAttacked( const Coordinate rm );

      // This method returns the current Item in the room, but does not
      // change it.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      Item GetItem( const Coordinate rm ) const;

      // This method takes the Item from the Room.
      // An exception is thrown if:
      //   There is no Item to take (i.e. Item::kNone or Item taken already)
      //     (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void TakeItem( const Coordinate rm );

      // This method drops the Treasure in the given room.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      void DropTreasure( const Coordinate rm );

      // This method returns the type of RoomBorder in the given direction.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      //   Direction d is kNone (invalid_argument)
      RoomBorder DirectionCheck( const Coordinate rm,
                                 const Direction d ) const;

  private:

    std::unique_ptr< std::unique_ptr<Room[]>[] > rooms_;
    const size_t x_size_;
    const size_t y_size_;
    const size_t MAX_X_SIZE_ = 20;
    const size_t MAX_Y_SIZE_ = 20;

    // Special rooms:
    //   Must be set before the game begins
    Coordinate spawn_1_;
    Coordinate spawn_2_;
    bool exit_set_ = false;
    bool treasure_set_ = false;  // Changed to false when the treasure is held
                                 // by a Player

    // This private method returns a reference to the Room at the given
    // coordinate.
    // An exception is thrown if:
    //   The Room is outside the Labyrinth (domain_error)
    Room& RoomAt( const Coordinate rm ) const;

    // This private method returns true if the Room is within the bounds of
    // the Labyrinth, and false otherwise.
    bool WithinBounds( const Coordinate rm ) const;

    // This private method returns true if the two Rooms are adjacent, and
    // false otherwise.
    // An exception is thrown if:
    //   One or both Rooms are outside the Labyrinth (domain_error)
    //   The same Room is given twice (logic_error)
    bool IsAdjacent( const Coordinate rm_1, const Coordinate rm_2 ) const;

};
<commit_msg>Laby: Adding explanation for unset default spawns.<commit_after>/*
 *
 * Author: Jeffrey Leung
 * Last edited: 2016-01-20
 *
 * This C++ header file contains the implementation of the Labyrinth class,
 * which uses the Room class to create a 2-d mapping for a game.
 *
 */

#pragma once

#include <memory>

#include "room_properties.hpp"
#include "room.hpp"
#include "coordinate.hpp"

// Rooms are indexed first with the y-coordinate, then with the x-coordinate.
class Labyrinth
{
  public:

    // The Coordinates of a Labyrinth begin at (0, 0) at the top left, and
    // end at (x_size-1, y_size-1) at the bottom right.

    // CONSTRUCTOR/DESTRUCTOR:

      // Parameterized constructor
      // An exception is thrown if:
      //   A size of 0 is given (domain_error)
      //   An x or y size greater than the maximum is given (domain_error)
      Labyrinth( const size_t x_size, const size_t y_size );

    // SETUP:

      // This method connects two Rooms by breaking their walls.
      // An exception is thrown if:
      //   The Rooms are already connected (logic_error)
      //   The Rooms are the same (logic_error)
      //   The Rooms are not adjacent (logic_error)
      //   One or both Rooms are outside the Labyrinth (domain_error)
      void ConnectRooms( const Coordinate rm_1, const Coordinate rm_2 );

      // This method sets the primary (initial) spawn Room.
      //   The Room is outside the Labyrinth (domain_error)
      void SetSpawn1( const Coordinate rm );

      // This method sets the secondary spawn Room.
      //   The Room is outside the Labyrinth (domain_error)
      void SetSpawn2( const Coordinate rm );

      // This method sets the exit of the Labyrinth on a Wall.
      // An exception is thrown if:
      //   The Direction has another Room (invalid_argument)
      //   The Exit has already been set (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void SetExit( const Coordinate rm, const Direction d );

      // This method places the Labyrinth treasure in a Room.
      // May be used to drop the Treasure if a Player is dead.
      // An exception is thrown if:
      //   The Treasure has already been placed in another Room (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void SetTreasure( const Coordinate rm );

      // This method places an Inhabitant in a Room.
      // Cannot change an existing Inhabitant; use the EnemyAttacked() method
      // for that.
      // An exception is thrown if:
      //   The Inhabitant of the Room has already been set (logic_error)
      //   Inhabitant inh is a null Inhabitant (i.e. Inhabitant::kNone)
      //     (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      void SetInhabitant( const Coordinate rm, const Inhabitant inh );

      // This method places an Item in a Room.
      // Cannot change an existing Item; use the TakeItem() method for that.
      // An exception is thrown if:
      //   The Item of the Room has already been set (logic_error)
      //   Item itm is a null Item (i.e. Item::kNone) (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      void SetItem( Coordinate rm, Item itm );

    // PLAY:

      // This method returns the current Inhabitant of the Room.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      Inhabitant GetInhabitant( const Coordinate rm ) const;

      // This method attacks the Inhabitant of the Room, and sets the resultant
      // Inhabitant.
      // The bullet is not removed from the Player.
      // True is returned if:
      //   The Inhabitant was a Minotaur
      // False is returned if:
      //   The Inhabitant was a Mirror
      // An exception is thrown if:
      //   There is no enemy to attack (i.e. Inhabitant::kNone, dead Minotaur,
      //     or cracked Mirror) (invalid_argument)
      //   The Room is outside the Labyrinth (domain_error)
      bool EnemyAttacked( const Coordinate rm );

      // This method returns the current Item in the room, but does not
      // change it.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      Item GetItem( const Coordinate rm ) const;

      // This method takes the Item from the Room.
      // An exception is thrown if:
      //   There is no Item to take (i.e. Item::kNone or Item taken already)
      //     (logic_error)
      //   The Room is outside the Labyrinth (domain_error)
      void TakeItem( const Coordinate rm );

      // This method drops the Treasure in the given room.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      void DropTreasure( const Coordinate rm );

      // This method returns the type of RoomBorder in the given direction.
      // An exception is thrown if:
      //   The Room is outside the Labyrinth (domain_error)
      //   Direction d is kNone (invalid_argument)
      RoomBorder DirectionCheck( const Coordinate rm,
                                 const Direction d ) const;

  private:

    std::unique_ptr< std::unique_ptr<Room[]>[] > rooms_;
    const size_t x_size_;
    const size_t y_size_;
    const size_t MAX_X_SIZE_ = 20;
    const size_t MAX_Y_SIZE_ = 20;

    // Special rooms:
    //   Should be set before the game begins
    //   Spawns will default to (0, 0) otherwise
    Coordinate spawn_1_;
    Coordinate spawn_2_;
    bool exit_set_ = false;
    bool treasure_set_ = false;  // Changed to false when the treasure is held
                                 // by a Player

    // This private method returns a reference to the Room at the given
    // coordinate.
    // An exception is thrown if:
    //   The Room is outside the Labyrinth (domain_error)
    Room& RoomAt( const Coordinate rm ) const;

    // This private method returns true if the Room is within the bounds of
    // the Labyrinth, and false otherwise.
    bool WithinBounds( const Coordinate rm ) const;

    // This private method returns true if the two Rooms are adjacent, and
    // false otherwise.
    // An exception is thrown if:
    //   One or both Rooms are outside the Labyrinth (domain_error)
    //   The same Room is given twice (logic_error)
    bool IsAdjacent( const Coordinate rm_1, const Coordinate rm_2 ) const;

};
<|endoftext|>


<commit_before>#include "mjolnir/nodeinfobuilder.h"
#include <valhalla/midgard/logging.h>
#include <math.h>

using namespace valhalla::baldr;

namespace {

const uint32_t ContinuityLookup[] = {0, 7, 13, 18, 22, 25, 27};

/**
 * Get the updated bit field.
 * @param dst  Data member to be updated.
 * @param src  Value to be updated.
 * @param pos  Position (pos element within the bit field).
 * @param len  Length of each element within the bit field.
 * @return  Returns an updated value for the bit field.
 */
uint32_t OverwriteBits(const uint32_t dst, const uint32_t src,
                       const uint32_t pos, const uint32_t len) {
  uint32_t shift = (pos * len);
  uint32_t mask  = (((uint32_t)1 << len) - 1) << shift;
  return (dst & ~mask) | (src << shift);
}

}

namespace valhalla {
namespace mjolnir {

NodeInfoBuilder::NodeInfoBuilder()
    : NodeInfo() {
}

NodeInfoBuilder::NodeInfoBuilder(const std::pair<float, float>& ll,
                                 const uint32_t edge_index,
                                 const uint32_t edge_count,
                                 const RoadClass rc,
                                 const uint32_t access,
                                 const NodeType type,
                                 const bool end,
                                 const bool traffic_signal)
    : NodeInfo() {
  set_latlng(ll);
  set_edge_index(edge_index);
  set_edge_count(edge_count);
  set_bestrc(rc);
  set_access(access);
  set_type(type);
  set_end(end);
  set_traffic_signal(traffic_signal);
}

// Sets the latitude and longitude.
void NodeInfoBuilder::set_latlng(const std::pair<float, float>& ll) {
  latlng_ = ll;
}

// Set the index in the node's tile of its first outbound edge.
void NodeInfoBuilder::set_edge_index(const uint32_t edge_index) {
  if (edge_index > kMaxTileEdgeCount) {
    // Consider this a catastrophic error
    throw std::runtime_error("NodeInfoBuilder: edge index exceeds max");
  }
  attributes_.edge_index_ = edge_index;
}

// Set the number of outbound directed edges.
void NodeInfoBuilder::set_edge_count(const uint32_t edge_count) {
  if (edge_count > kMaxEdgesPerNode) {
    // Log an error and set count to max.
    LOG_ERROR("NodeInfoBuilder: edge count exceeds max: " +
              std::to_string(edge_count));
    attributes_.edge_count_ = kMaxEdgesPerNode;
  } else {
    attributes_.edge_count_ = edge_count;
  }
}

// Set the best road class of the outbound directed edges.
void NodeInfoBuilder::set_bestrc(const RoadClass bestrc) {
   attributes_.bestrc_ = static_cast<uint32_t>(bestrc);
}

// Set the access modes (bit mask) allowed to pass through the node.
void NodeInfoBuilder::set_access(const uint32_t access) {
  access_.v = access;
}

// Set the intersection type.
void NodeInfoBuilder::set_intersection(const IntersectionType type) {
  intersection_ = type;
}

// Set the index of the administrative information within this tile.
void NodeInfoBuilder::set_admin_index(const uint16_t admin_index) {
  admin_.admin_index = admin_index;
}

// Set the timezone index.
void NodeInfoBuilder::set_timezone(const uint16_t timezone) {
  admin_.timezone = timezone;
}

// Set the daylight saving time flag
void NodeInfoBuilder::set_dst(const bool dst) {
  admin_.dst = dst;
}

// Set the driveability of the local directed edge given a local
// edge index.
void NodeInfoBuilder::set_local_driveability(const uint32_t localidx,
                                             const Driveability d) {
  if (localidx > kMaxLocalEdgeIndex) {
    LOG_WARN("Exceeding max local index on set_local_driveability - skip");
  } else {
    type_.local_driveability = OverwriteBits(type_.local_driveability,
                 static_cast<uint32_t>(d), localidx, 2);
  }
}

// Set the relative density
void NodeInfoBuilder::set_density(const uint32_t density) {
  if (density > kMaxDensity) {
    LOG_WARN("Exceeding max. density: " + std::to_string(density));
    type_.density = kMaxDensity;
  } else {
    type_.density = density;
  }
}

// Set the node type.
void NodeInfoBuilder::set_type(const NodeType type) {
  type_.type =  static_cast<uint8_t>(type);
}

// Set the number of driveable edges on the local level. Subtract 1 so
// a value up to kMaxLocalEdgeIndex+1 can be stored.
void NodeInfoBuilder::set_local_edge_count(const uint32_t n) {
  if (n > kMaxLocalEdgeIndex+1) {
    LOG_INFO("Exceeding max. local edge count: " + std::to_string(n));
    type_.local_edge_count = kMaxLocalEdgeIndex;
  } else if (n == 0) {
    LOG_ERROR("Node with 0 local edges found");
  } else {
    type_.local_edge_count = n - 1;
  }
}

// Set the dead-end node flag.
void NodeInfoBuilder::set_end(const bool end) {
  type_.end = end;
}

// Set the parent node flag (e.g. a parent transit stop).
void NodeInfoBuilder::set_parent(const bool parent) {
  type_.parent = parent;
}

// Set the child node flag (e.g. a child transit stop).
void NodeInfoBuilder::set_child(const bool child) {
  type_.child = child;
}

// Sets the flag indicating a mode change is allowed at this node.
// The access data tells which modes are allowed at the node. Examples
// include transit stops, bike share locations, and parking locations.
void NodeInfoBuilder::set_mode_change(const bool mc) {
  type_.mode_change = mc;
}

// Set the traffic signal flag.
void NodeInfoBuilder::set_traffic_signal(const bool traffic_signal) {
  type_.traffic_signal = traffic_signal;
}

// Set the transit stop Id.
void NodeInfoBuilder::set_stop_id(const uint32_t stop_id) {
  stop_.stop_id = stop_id;
}

/**
 * Set the name consistency between a pair of local edges. This is limited
 * to the first 8 local edge indexes.
 * @param  from  Local index of the from edge.
 * @param  to    Local index of the to edge.
 * @param  c     Are names consistent between the 2 edges?
 */
void NodeInfoBuilder::set_name_consistency(const uint32_t from,
                                           const uint32_t to,
                                           const bool c) {
  if (from == to) {
    return;
  } else if (from > kMaxLocalEdgeIndex || to > kMaxLocalEdgeIndex) {
    LOG_WARN("Local index exceeds max in set_name_consistency, skip");
  } else {
    if (from < to) {
      stop_.name_consistency = OverwriteBits(stop_.name_consistency, c,
                   (ContinuityLookup[from] + (to-from-1)), 1);
    } else {
      stop_.name_consistency = OverwriteBits(stop_.name_consistency, c,
                   (ContinuityLookup[to] + (from-to-1)), 1);
    }
  }
}

// Set the heading of the local edge given its local index. Supports
// up to 8 local edges. Headings are reduced to 8 bits.
void NodeInfoBuilder::set_heading(uint32_t localidx, uint32_t heading) {
  if (localidx > kMaxLocalEdgeIndex) {
    LOG_WARN("Local index exceeds max in set_heading, skip");
  } else {
    // Has to be 64 bit!
    uint64_t hdg = static_cast<uint64_t>(round(
        (heading % 360) * kHeadingShrinkFactor));
    headings_ |= hdg << static_cast<uint64_t>(localidx * 8);
  }
}

}
}
<commit_msg>Switched to use c++ lib<commit_after>#include "mjolnir/nodeinfobuilder.h"
#include <valhalla/midgard/logging.h>
#include <cmath>

using namespace valhalla::baldr;

namespace {

const uint32_t ContinuityLookup[] = {0, 7, 13, 18, 22, 25, 27};

/**
 * Get the updated bit field.
 * @param dst  Data member to be updated.
 * @param src  Value to be updated.
 * @param pos  Position (pos element within the bit field).
 * @param len  Length of each element within the bit field.
 * @return  Returns an updated value for the bit field.
 */
uint32_t OverwriteBits(const uint32_t dst, const uint32_t src,
                       const uint32_t pos, const uint32_t len) {
  uint32_t shift = (pos * len);
  uint32_t mask  = (((uint32_t)1 << len) - 1) << shift;
  return (dst & ~mask) | (src << shift);
}

}

namespace valhalla {
namespace mjolnir {

NodeInfoBuilder::NodeInfoBuilder()
    : NodeInfo() {
}

NodeInfoBuilder::NodeInfoBuilder(const std::pair<float, float>& ll,
                                 const uint32_t edge_index,
                                 const uint32_t edge_count,
                                 const RoadClass rc,
                                 const uint32_t access,
                                 const NodeType type,
                                 const bool end,
                                 const bool traffic_signal)
    : NodeInfo() {
  set_latlng(ll);
  set_edge_index(edge_index);
  set_edge_count(edge_count);
  set_bestrc(rc);
  set_access(access);
  set_type(type);
  set_end(end);
  set_traffic_signal(traffic_signal);
}

// Sets the latitude and longitude.
void NodeInfoBuilder::set_latlng(const std::pair<float, float>& ll) {
  latlng_ = ll;
}

// Set the index in the node's tile of its first outbound edge.
void NodeInfoBuilder::set_edge_index(const uint32_t edge_index) {
  if (edge_index > kMaxTileEdgeCount) {
    // Consider this a catastrophic error
    throw std::runtime_error("NodeInfoBuilder: edge index exceeds max");
  }
  attributes_.edge_index_ = edge_index;
}

// Set the number of outbound directed edges.
void NodeInfoBuilder::set_edge_count(const uint32_t edge_count) {
  if (edge_count > kMaxEdgesPerNode) {
    // Log an error and set count to max.
    LOG_ERROR("NodeInfoBuilder: edge count exceeds max: " +
              std::to_string(edge_count));
    attributes_.edge_count_ = kMaxEdgesPerNode;
  } else {
    attributes_.edge_count_ = edge_count;
  }
}

// Set the best road class of the outbound directed edges.
void NodeInfoBuilder::set_bestrc(const RoadClass bestrc) {
   attributes_.bestrc_ = static_cast<uint32_t>(bestrc);
}

// Set the access modes (bit mask) allowed to pass through the node.
void NodeInfoBuilder::set_access(const uint32_t access) {
  access_.v = access;
}

// Set the intersection type.
void NodeInfoBuilder::set_intersection(const IntersectionType type) {
  intersection_ = type;
}

// Set the index of the administrative information within this tile.
void NodeInfoBuilder::set_admin_index(const uint16_t admin_index) {
  admin_.admin_index = admin_index;
}

// Set the timezone index.
void NodeInfoBuilder::set_timezone(const uint16_t timezone) {
  admin_.timezone = timezone;
}

// Set the daylight saving time flag
void NodeInfoBuilder::set_dst(const bool dst) {
  admin_.dst = dst;
}

// Set the driveability of the local directed edge given a local
// edge index.
void NodeInfoBuilder::set_local_driveability(const uint32_t localidx,
                                             const Driveability d) {
  if (localidx > kMaxLocalEdgeIndex) {
    LOG_WARN("Exceeding max local index on set_local_driveability - skip");
  } else {
    type_.local_driveability = OverwriteBits(type_.local_driveability,
                 static_cast<uint32_t>(d), localidx, 2);
  }
}

// Set the relative density
void NodeInfoBuilder::set_density(const uint32_t density) {
  if (density > kMaxDensity) {
    LOG_WARN("Exceeding max. density: " + std::to_string(density));
    type_.density = kMaxDensity;
  } else {
    type_.density = density;
  }
}

// Set the node type.
void NodeInfoBuilder::set_type(const NodeType type) {
  type_.type =  static_cast<uint8_t>(type);
}

// Set the number of driveable edges on the local level. Subtract 1 so
// a value up to kMaxLocalEdgeIndex+1 can be stored.
void NodeInfoBuilder::set_local_edge_count(const uint32_t n) {
  if (n > kMaxLocalEdgeIndex+1) {
    LOG_INFO("Exceeding max. local edge count: " + std::to_string(n));
    type_.local_edge_count = kMaxLocalEdgeIndex;
  } else if (n == 0) {
    LOG_ERROR("Node with 0 local edges found");
  } else {
    type_.local_edge_count = n - 1;
  }
}

// Set the dead-end node flag.
void NodeInfoBuilder::set_end(const bool end) {
  type_.end = end;
}

// Set the parent node flag (e.g. a parent transit stop).
void NodeInfoBuilder::set_parent(const bool parent) {
  type_.parent = parent;
}

// Set the child node flag (e.g. a child transit stop).
void NodeInfoBuilder::set_child(const bool child) {
  type_.child = child;
}

// Sets the flag indicating a mode change is allowed at this node.
// The access data tells which modes are allowed at the node. Examples
// include transit stops, bike share locations, and parking locations.
void NodeInfoBuilder::set_mode_change(const bool mc) {
  type_.mode_change = mc;
}

// Set the traffic signal flag.
void NodeInfoBuilder::set_traffic_signal(const bool traffic_signal) {
  type_.traffic_signal = traffic_signal;
}

// Set the transit stop Id.
void NodeInfoBuilder::set_stop_id(const uint32_t stop_id) {
  stop_.stop_id = stop_id;
}

/**
 * Set the name consistency between a pair of local edges. This is limited
 * to the first 8 local edge indexes.
 * @param  from  Local index of the from edge.
 * @param  to    Local index of the to edge.
 * @param  c     Are names consistent between the 2 edges?
 */
void NodeInfoBuilder::set_name_consistency(const uint32_t from,
                                           const uint32_t to,
                                           const bool c) {
  if (from == to) {
    return;
  } else if (from > kMaxLocalEdgeIndex || to > kMaxLocalEdgeIndex) {
    LOG_WARN("Local index exceeds max in set_name_consistency, skip");
  } else {
    if (from < to) {
      stop_.name_consistency = OverwriteBits(stop_.name_consistency, c,
                   (ContinuityLookup[from] + (to-from-1)), 1);
    } else {
      stop_.name_consistency = OverwriteBits(stop_.name_consistency, c,
                   (ContinuityLookup[to] + (from-to-1)), 1);
    }
  }
}

// Set the heading of the local edge given its local index. Supports
// up to 8 local edges. Headings are reduced to 8 bits.
void NodeInfoBuilder::set_heading(uint32_t localidx, uint32_t heading) {
  if (localidx > kMaxLocalEdgeIndex) {
    LOG_WARN("Local index exceeds max in set_heading, skip");
  } else {
    // Has to be 64 bit!
    uint64_t hdg = static_cast<uint64_t>(std::round(
        (heading % 360) * kHeadingShrinkFactor));
    headings_ |= hdg << static_cast<uint64_t>(localidx * 8);
  }
}

}
}
<|endoftext|>