<commit_before>#include "cbase.h"

#include "openal_oggsample.h"
#include "openal_wavsample.h"
#include "openal_mp3sample.h"

#include "openal_sample_pool.h"

CSamplePool      g_OpenALSamplePool;

// Stolen from IEngineSound.h
#define SOUND_FROM_LOCAL_PLAYER		-1
#define SOUND_FROM_WORLD			0

CSamplePool::CSamplePool()
{
    m_SamplePool.Purge();
    m_iLastID = SAMPLE_HANDLE_INVALID;
}

CSamplePool::~CSamplePool()
{
    m_SamplePool.Purge();
}

bool CSamplePool::ShouldHandleThisSound(const char *filename)
{
    if (Q_stristr(filename, ".ogg") /* || Q_stristr(filename, ".wav") */ )
    {
        return true;
    }

    return false;
}

CodecType CSamplePool::GetCodecFromFileName( const char *filename )
{
    if (Q_stristr(filename, ".ogg") )
    {
        return CODEC_OGG;
    }

    if (Q_stristr(filename, ".wav") )
    {
        return CODEC_WAV;
    }

    if (Q_stristr(filename, ".mp3"))
    {
        return CODEC_MP3;
    }

    return CODEC_NONE;
}

SampleHandle_t CSamplePool::GetNewHandle()
{
    m_iLastID += 1;
    return m_iLastID;
}

SampleHandle_t CSamplePool::CreateNewSample(const char *filename, const EmitSound_t &ep, bool shouldPlay /* = true */ )
{
    SampleHandle_t handle = CreateNewSample(filename, shouldPlay);
    SetParameters(handle, ep);

    return handle;
}

SampleHandle_t CSamplePool::CreateNewSample(const char *filename, bool shouldPlay /* = true */ )
{
    // NOTENOTE:    Consider paths to be of proper format
    //              when they arrive here

    // Remove any snd chars
    //const char *name = PSkipSoundChars(filename);
    IOpenALSample *newSample = NULL;

    // Figure out the proper codec
    CodecType codec = GetCodecFromFileName(filename);
    switch (codec)
    {
    case CODEC_OGG:
        newSample = new COpenALOggSample();
        break;
    case CODEC_WAV:
        newSample = new COpenALWavSample();
        break;
    case CODEC_MP3:
        newSample = new COpenALMp3Sample();
        break;
    //case CODEC_NONE:
    default:
        Warning("Unable to resolve codec for %s", filename);
        return SAMPLE_HANDLE_INVALID;
    }

    newSample->Open(filename);

    newSample->SetLooping(false);
    newSample->SetPositional(false);

    SampleData_t data;
    data.sample = newSample;
    data.codec = codec;
    data.handle = GetNewHandle();

    Msg("Sound %s played through OpenAL\n", filename);

    AUTO_LOCK_FM(m_SamplePool);

    m_SamplePool.AddToTail(data);
    return data.handle;
}

SampleData_t* CSamplePool::AquireSampleFromHandle( SampleHandle_t handle )
{
    if (handle == SAMPLE_HANDLE_INVALID)
    {
        return NULL;
    }

    int i = 0;

    while ( i < m_SamplePool.Count() )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            // This blows...
            break;
        }

        SampleData_t *data = &m_SamplePool[i];
        if ( data->handle != handle )
        {
            i += 1;
            continue;;
        }

        return data;
    }

    return NULL;
}

void CSamplePool::SetParameters( SampleHandle_t handle, const EmitSound_t &ep )
{
    SampleData_t *data = AquireSampleFromHandle(handle);

    if (!data)
        return;

    data->sample->SetGain(ep.m_flVolume);

    if (ep.m_nSpeakerEntity != SOUND_FROM_LOCAL_PLAYER)
    {
        CBaseEntity *pEnt = CBaseEntity::Instance( ep.m_nSpeakerEntity );
        if (pEnt!= NULL)
        {
            data->sample->LinkEntity( pEnt );
        }

        if (ep.m_pOrigin)
        {
            data->sample->SetPosition(ep.m_pOrigin->x, ep.m_pOrigin->y, ep.m_pOrigin->z );
        }
    }
}

void CSamplePool::Stop( SampleHandle_t handle )
{
    AUTO_LOCK_FM(m_SamplePool);

    SampleData_t *data = AquireSampleFromHandle(handle);

    if (!data)
    {
        return;
    }

    data->wants_stop = true;
}

void CSamplePool::PreFrame()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        return;
    }

    int i = 0;

    while ( true )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            break;
        }

        SampleData_t data = m_SamplePool[i];

        // Is the sample invalid?
        if ( data.sample == NULL )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);

            i += 1;
            continue;
        }

        if (data.codec == CODEC_NONE)
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);

            i += 1;
            continue;
        }

        if ( data.sample->IsFinished() && !data.sample->IsPlaying() )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);
        }

        i += 1;
    }

    data->wants_stop = true;
}

void CSamplePool::Frame()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        return;
    }

    int i = 0;

    while ( true )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            break;
        }

        SampleData_t data = m_SamplePool[i];

        // Is the sample invalid?
        if ( data.sample == NULL )
        {
            i += 1;
            continue;
        }

        Assert( data.codec != CODEC_NONE);
        if (data.codec == CODEC_NONE)
        {
            i += 1;
            continue;
        }

        if ( data.sample->IsFinished() && !data.sample->IsPlaying() )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);
            continue;
        }

        if ( data.sample->IsReady() )
        {
            data.sample->Update(gpGlobals->curtime);

            if ( !data.sample->IsPlaying() && !data.sample->IsFinished() )
            {
                data.sample->Play();
            }
            else if (data.wants_stop)
            {
                data.sample->Stop();
            }
        }

        i += 1;
    }

}

void CSamplePool::PostFrame()
{

}

void CSamplePool::Update()
{
}

void CSamplePool::Shutdown()
{
    PurgeAll();
}

void CSamplePool::PurgeAll()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        // We like optimizations
        return;
    }

    int i = 0;

    while ( i < m_SamplePool.Count() )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            // This blows...
            i += 1;
            continue;
        }

        IOpenALSample *pSample = m_SamplePool[i].sample;

        if (pSample == NULL)
        {
            i += 1;
            continue;
        }

        pSample->Destroy();
        delete pSample;

        pSample = NULL;

        m_SamplePool.Remove(i);
    }
}

CON_COMMAND(openal_purge_samples, "Purges all samples in the pool")
{
    g_OpenALSamplePool.PurgeAll();
}<commit_msg>Added mp3 sample with decoding and streaming Added libmad lib and header Added debugging console commands for mp3 sample Fixed an error output not working in the base sample Added functionality for loading mp3 files in the sample pool<commit_after>#include "cbase.h"

#include "openal_oggsample.h"
#include "openal_wavsample.h"
#include "openal_mp3sample.h"

#include "openal_sample_pool.h"

CSamplePool      g_OpenALSamplePool;

// Stolen from IEngineSound.h
#define SOUND_FROM_LOCAL_PLAYER		-1
#define SOUND_FROM_WORLD			0

CSamplePool::CSamplePool()
{
    m_SamplePool.Purge();
    m_iLastID = SAMPLE_HANDLE_INVALID;
}

CSamplePool::~CSamplePool()
{
    m_SamplePool.Purge();
}

bool CSamplePool::ShouldHandleThisSound(const char *filename)
{
    if (Q_stristr(filename, ".ogg") /* || Q_stristr(filename, ".wav") */ )
    {
        return true;
    }

    return false;
}

CodecType CSamplePool::GetCodecFromFileName( const char *filename )
{
    if (Q_stristr(filename, ".ogg") )
    {
        return CODEC_OGG;
    }

    if (Q_stristr(filename, ".wav") )
    {
        return CODEC_WAV;
    }

    if (Q_stristr(filename, ".mp3"))
    {
        return CODEC_MP3;
    }

    return CODEC_NONE;
}

SampleHandle_t CSamplePool::GetNewHandle()
{
    m_iLastID += 1;
    return m_iLastID;
}

SampleHandle_t CSamplePool::CreateNewSample(const char *filename, const EmitSound_t &ep, bool shouldPlay /* = true */ )
{
    SampleHandle_t handle = CreateNewSample(filename, shouldPlay);
    SetParameters(handle, ep);

    return handle;
}

SampleHandle_t CSamplePool::CreateNewSample(const char *filename, bool shouldPlay /* = true */ )
{
    // NOTENOTE:    Consider paths to be of proper format
    //              when they arrive here

    // Remove any snd chars
    //const char *name = PSkipSoundChars(filename);
    IOpenALSample *newSample = NULL;

    // Figure out the proper codec
    CodecType codec = GetCodecFromFileName(filename);
    switch (codec)
    {
    case CODEC_OGG:
        newSample = new COpenALOggSample();
        break;
    case CODEC_WAV:
        newSample = new COpenALWavSample();
        break;
    case CODEC_MP3:
        newSample = new COpenALMp3Sample();
        break;
    //case CODEC_NONE:
    default:
        Warning("Unable to resolve codec for %s", filename);
        return SAMPLE_HANDLE_INVALID;
    }

    newSample->Open(filename);

    newSample->SetLooping(false);
    newSample->SetPositional(false);

    SampleData_t data;
    data.sample = newSample;
    data.codec = codec;
    data.handle = GetNewHandle();

    Msg("Sound %s played through OpenAL\n", filename);

    AUTO_LOCK_FM(m_SamplePool);

    m_SamplePool.AddToTail(data);
    return data.handle;
}

SampleData_t* CSamplePool::AquireSampleFromHandle( SampleHandle_t handle )
{
    if (handle == SAMPLE_HANDLE_INVALID)
    {
        return NULL;
    }

    int i = 0;

    while ( i < m_SamplePool.Count() )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            // This blows...
            break;
        }

        SampleData_t *data = &m_SamplePool[i];
        if ( data->handle != handle )
        {
            i += 1;
            continue;;
        }

        return data;
    }

    return NULL;
}

void CSamplePool::SetParameters( SampleHandle_t handle, const EmitSound_t &ep )
{
    SampleData_t *data = AquireSampleFromHandle(handle);

    if (!data)
        return;

    data->sample->SetGain(ep.m_flVolume);

    if (ep.m_nSpeakerEntity != SOUND_FROM_LOCAL_PLAYER)
    {
        CBaseEntity *pEnt = CBaseEntity::Instance( ep.m_nSpeakerEntity );
        if (pEnt!= NULL)
        {
            data->sample->LinkEntity( pEnt );
        }

        if (ep.m_pOrigin)
        {
            data->sample->SetPosition(ep.m_pOrigin->x, ep.m_pOrigin->y, ep.m_pOrigin->z );
        }
    }
}

void CSamplePool::Stop( SampleHandle_t handle )
{
    AUTO_LOCK_FM(m_SamplePool);

    SampleData_t *data = AquireSampleFromHandle(handle);

    if (!data)
    {
        return;
    }

    data->wants_stop = true;
}

void CSamplePool::PreFrame()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        return;
    }

    int i = 0;

    while ( true )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            break;
        }

        SampleData_t data = m_SamplePool[i];

        // Is the sample invalid?
        if ( data.sample == NULL )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);

            i += 1;
            continue;
        }

        if (data.codec == CODEC_NONE)
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);

            i += 1;
            continue;
        }

        if ( data.sample->IsFinished() && !data.sample->IsPlaying() )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);
        }

        i += 1;
    }

    data->wants_stop = true;
}

void CSamplePool::Frame()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        return;
    }

    int i = 0;

    while ( true )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            break;
        }

        SampleData_t data = m_SamplePool[i];

        // Is the sample invalid?
        if ( data.sample == NULL )
        {
            i += 1;
            continue;
        }

        Assert( data.codec != CODEC_NONE);
        if (data.codec == CODEC_NONE)
        {
            i += 1;
            continue;
        }

        if ( data.sample->IsFinished() && !data.sample->IsPlaying() )
        {
            IOpenALSample *pSample = data.sample;

            pSample->Destroy();
            delete pSample;

            pSample = NULL;

            m_SamplePool.Remove(i);
            continue;
        }

        if ( data.sample->IsReady() )
        {
            data.sample->Update(gpGlobals->curtime);

            if ( !data.sample->IsPlaying() && !data.sample->IsFinished() )
            {
                data.sample->Play();
            }
            else if (data.wants_stop)
            {
                data.sample->Stop();
            }
        }

        i += 1;
    }

}

void CSamplePool::PostFrame()
{

}

void CSamplePool::Update()
{
}

void CSamplePool::Shutdown()
{
    PurgeAll();
}

void CSamplePool::PurgeAll()
{
    AUTO_LOCK_FM(m_SamplePool);

    if (!m_SamplePool.Count())
    {
        // We like optimizations
        return;
    }

    int i = 0;

    while ( i < m_SamplePool.Count() )
    {
        if (!m_SamplePool.IsValidIndex(i))
        {
            // This blows...
            i += 1;
            continue;
        }

        IOpenALSample *pSample = m_SamplePool[i].sample;

        if (pSample == NULL)
        {
            i += 1;
            continue;
        }

        pSample->Destroy();
        delete pSample;

        pSample = NULL;

        m_SamplePool.Remove(i);
    }
}

CON_COMMAND(openal_purge_samples, "Purges all samples in the pool")
{
    g_OpenALSamplePool.PurgeAll();
}<|endoftext|>


<commit_before>//------------ standard header -----------------------------------//
#include "stdlibrary.h"
//------------ end of standard header ----------------------------//
#include "library.h"
#include <stdlib.h>
#include <string.h>
#include "AnsiString.h"
#include <julius/julius.h>

static INVOKE_CALL InvokePtr = 0;

CONCEPT_DLL_API ON_CREATE_CONTEXT MANAGEMENT_PARAMETERS {
    InvokePtr = Invoke;
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_POWER)
    DEFINE_ECONSTANT(J_RESULT_STATUS_TERMINATE)
    DEFINE_ECONSTANT(J_RESULT_STATUS_ONLY_SILENCE)
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_GMM)
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_SHORT)
    DEFINE_ECONSTANT(J_RESULT_STATUS_FAIL)
    DEFINE_ECONSTANT(J_RESULT_STATUS_SUCCESS)
    return 0;
}
//=====================================================================================//
CONCEPT_DLL_API ON_DESTROY_CONTEXT MANAGEMENT_PARAMETERS {
    return 0;
}
//=====================================================================================//
static void status_recog_event(Recog *recog, void *delegate) {
    void *RES             = 0;
    void *EXCEPTION       = 0;

    if (delegate) {
        InvokePtr(INVOKE_CALL_DELEGATE, delegate, &RES, &EXCEPTION, (INTEGER)0);//, (INTEGER)VARIABLE_NUMBER, (char *)"", (double)(SYS_INT)0);
        if (EXCEPTION)
            InvokePtr(INVOKE_FREE_VARIABLE, EXCEPTION);
        if (RES) {
            INTEGER type  = 0;
            NUMBER  nData = 0;
            char    *str  = 0;

            InvokePtr(INVOKE_GET_VARIABLE, RES, &type, &str, &nData);
            if ((type == VARIABLE_NUMBER) && (nData == 1))
                j_request_terminate(recog);
            InvokePtr(INVOKE_FREE_VARIABLE, RES);
        }
    }
}

static AnsiString put_hypo_phoneme(WORD_ID *seq, int n, WORD_INFO *winfo) {
    int         i, j;
    WORD_ID     w;
    AnsiString  res;
    static char buf[MAX_HMMNAME_LEN];

    if (seq != NULL)
        for (i = 0; i < n; i++) {
            if (i > 0)
                res += (char *)" |";
            w = seq[i];
            for (j = 0; j < winfo->wlen[w]; j++) {
                if (j)
                    res += (char *)" ";
                center_name(winfo->wseq[w][j]->name, buf);
                res += buf;
            }
        }
    return res;
}

static void output_result(Recog *recog, void *delegate) {
    int          i, j;
    int          len;
    WORD_INFO    *winfo;
    WORD_ID      *seq;
    int          seqnum;
    int          n;
    Sentence     *s;
    RecogProcess *r;
    HMM_Logical  *p;

    INVOKE_CALL Invoke = InvokePtr;
    void *var = 0;
    CREATE_VARIABLE(var);
    CREATE_ARRAY(var);

    /* all recognition results are stored at each recognition process
     * instance */
    bool       has_data = false;

    INTEGER idx = 0;
    for (r = recog->process_list; r; r = r->next) {
        /* skip the process if the process is not alive */
        if (!r->live)
            continue;

        /* result are in r->result.  See recog.h for details */

        void *var2 = 0;
        Invoke(INVOKE_ARRAY_VARIABLE, var, (INTEGER)idx++, &var2);
        /* check result status */
        if (r->result.status < 0) {         /* no results obtained */
            /* outout message according to the status code */
            Invoke(INVOKE_SET_VARIABLE, var2, (INTEGER)VARIABLE_NUMBER, "", (NUMBER)r->result.status);
            continue;
        }

        /* output results for all the obtained sentences */
        winfo = r->lm->winfo;

        CREATE_ARRAY(var2);
        INTEGER idx2 = 0;
        for (n = 0; n < r->result.sentnum; n++) {         /* for all sentences */
            has_data = true;
            s        = &(r->result.sent[n]);
            seq      = s->word;
            seqnum   = s->word_num;
            if (!seqnum)
                continue;

            void *var3 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE, var2, (INTEGER)idx2++, &var3);
            CREATE_ARRAY(var3);

            void *var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, (INTEGER)"s", &var4);
            CREATE_ARRAY(var4);

            /* output word sequence like Julius */
            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_STRING, winfo->woutput[seq[i]], (NUMBER)0);

            var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, (INTEGER)"wsek", &var4);
            CREATE_ARRAY(var4);

            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_STRING, winfo->wname[seq[i]], (NUMBER)0);

            /* phoneme sequence */
            AnsiString phoneme(put_hypo_phoneme(seq, seqnum, winfo));
            if (phoneme.Length())
                Invoke(INVOKE_SET_ARRAY_ELEMENT_BY_KEY, var3, "phoneme", (INTEGER)VARIABLE_STRING, phoneme.c_str(), (NUMBER)phoneme.Length());

            var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, (INTEGER)"score", &var4);
            CREATE_ARRAY(var4);

            /* confidence scores */
            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_NUMBER, "", (NUMBER)s->confidence[i]);
        }
    }
    if (delegate) {
        void *RES             = 0;
        void *EXCEPTION       = 0;

        INTEGER type  = 0;
        NUMBER  nData = 0;
        char    *str  = 0;

        InvokePtr(INVOKE_GET_VARIABLE, var, &type, &str, &nData);

        InvokePtr(INVOKE_CALL_DELEGATE, delegate, &RES, &EXCEPTION, (INTEGER)1, (INTEGER)type, str, nData);
        if (EXCEPTION)
            InvokePtr(INVOKE_FREE_VARIABLE, EXCEPTION);
        if (RES) {
            InvokePtr(INVOKE_GET_VARIABLE, RES, &type, &str, &nData);
            if ((type == VARIABLE_NUMBER) && (nData))
                j_request_terminate(recog);
            InvokePtr(INVOKE_FREE_VARIABLE, RES);
        }
    }
    FREE_VARIABLE(var);
}

CONCEPT_FUNCTION_IMPL_MINMAX_PARAMS(SpeechLoop, 1, 2)
    T_ARRAY("SpeechLoop", 0)
    int count = Invoke(INVOKE_GET_ARRAY_COUNT, PARAMETER(0));
    int argc = 1;
    char **argv = (char **)malloc((count * 2 + 1) * sizeof(char *));
    argv[0] = "SpeechLoop";
    bool has_mic = true;
    char *empty = (char *)"";
    void *on_result = 0;
    void *on_start = 0;
    void *on_stop = 0;
    void *on_ready = 0;
    void *on_recog_start = 0;
    void *on_recog_end = 0;
    char *stream = NULL;
    if (count > 0) {
        for (INTEGER i = 0; i < count; i++) {
            char *key = 0;
            Invoke(INVOKE_GET_ARRAY_KEY, PARAMETER(0), i, &key);
            INTEGER type  = 0;
            NUMBER  dummy = 0;
            char    *str  = 0;

            if (key) {
                Invoke(INVOKE_GET_ARRAY_ELEMENT_BY_KEY, PARAMETER(0), key, &type, &str, &dummy);
                if (strcmp(key, "OnResult") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_result);
                } else
                if (strcmp(key, "OnStart") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_start);
                } else
                if (strcmp(key, "OnStop") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_stop);
                } else
                if (strcmp(key, "OnReady") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_ready);
                } else
                if (strcmp(key, "OnRecognitionStart") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_recog_start);
                } else
                if (strcmp(key, "OnRecognitionEnd") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_recog_end);
                } else
                if (strcmp(key, "InputName") == 0) {
                    if (type == VARIABLE_STRING)
                        stream = str;
                } else
                if ((key) && (!strcmp(key, "j_adin_init"))) {
                    if (type == VARIABLE_NUMBER)
                        has_mic = (bool)(int)dummy;
                } else
                    argv[argc++] = key;
            } else
                Invoke(INVOKE_GET_ARRAY_ELEMENT, PARAMETER(0), i, &type, &str, &dummy);
            switch (type) {
                case VARIABLE_STRING:
                    if ((str) && (str[0]))
                        argv[argc++] = str;
                    else
                        argv[argc++] = empty;
                    break;
            }
        }
    }
    if (PARAMETERS_COUNT > 1) {
        SET_STRING(1, "");
    }

    Jconf *jconf = j_config_load_args_new(argc, argv);
    if (!jconf) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_config_load_args_new");
        }
        free(argv);
        RETURN_NUMBER(-1);
        return 0;
    }

    Recog *recog = j_create_instance_from_jconf(jconf);
    if (!recog) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_create_instance_from_jconf");
        }
        j_jconf_free(jconf);
        free(argv);
        RETURN_NUMBER(-2);
        return 0;
    }

    if ((has_mic) && (j_adin_init(recog) == FALSE)) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_adin_init");
        }
        // called by j_recog_free
        // j_jconf_free(jconf);
        j_recog_free(recog);
        free(argv);
        return 0;
    }

    if (on_ready) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_READY, status_recog_event, on_ready);
        Invoke(INVOKE_LOCK_VARIABLE, on_ready);
    }
    if (on_start) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_START, status_recog_event, on_start);
        Invoke(INVOKE_LOCK_VARIABLE, on_start);
    }
    if (on_stop) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_STOP, status_recog_event, on_stop);
        Invoke(INVOKE_LOCK_VARIABLE, on_stop);
    }
    if (on_recog_start) {
        // callback_add(recog, CALLBACK_EVENT_RECOGNITION_START status_recog_event, on_recog_start);
        Invoke(INVOKE_LOCK_VARIABLE, on_recog_start);
    }
    if (on_recog_end) {
        // callback_add(recog, CALLBACK_EVENT_RECOGNITION_END, status_recog_event, on_recog_end);
        Invoke(INVOKE_LOCK_VARIABLE, on_recog_end);
    }

    if (on_result)
        callback_add(recog, CALLBACK_RESULT, output_result, on_result);

    bool stream_ok = false;
    switch (j_open_stream(recog, stream)) {
        case 0:
            stream_ok = true;
            break;

        case -1:
            if (PARAMETERS_COUNT > 1) {
                SET_STRING(1, "error in input stream");
            }
            break;

        case -2:
            if (PARAMETERS_COUNT > 1) {
                SET_STRING(1, "failed to begin input stream");
            }
            break;
    }

    int ret = -1;
    if (stream_ok)
        ret = j_recognize_stream(recog);
    // called by j_recog_free
    // if (jconf)
    //     j_jconf_free(jconf);
    if (stream_ok)
        j_close_stream(recog);
    j_recog_free(recog);
    free(argv);

    if (on_ready)
        Invoke(INVOKE_FREE_VARIABLE, on_ready);

    if (on_start)
        Invoke(INVOKE_FREE_VARIABLE, on_start);

    if (on_stop)
        Invoke(INVOKE_FREE_VARIABLE, on_stop);

    if (on_recog_start)
        Invoke(INVOKE_FREE_VARIABLE, on_recog_start);

    if (on_recog_end)
        Invoke(INVOKE_FREE_VARIABLE, on_recog_end);

    RETURN_NUMBER(0);
END_IMPL
//=====================================================================================//
<commit_msg>Fixed bug on 64bit<commit_after>//------------ standard header -----------------------------------//
#include "stdlibrary.h"
//------------ end of standard header ----------------------------//
#include "library.h"
#include <stdlib.h>
#include <string.h>
#include "AnsiString.h"
#include <julius/julius.h>

static INVOKE_CALL InvokePtr = 0;

CONCEPT_DLL_API ON_CREATE_CONTEXT MANAGEMENT_PARAMETERS {
    InvokePtr = Invoke;
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_POWER)
    DEFINE_ECONSTANT(J_RESULT_STATUS_TERMINATE)
    DEFINE_ECONSTANT(J_RESULT_STATUS_ONLY_SILENCE)
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_GMM)
    DEFINE_ECONSTANT(J_RESULT_STATUS_REJECT_SHORT)
    DEFINE_ECONSTANT(J_RESULT_STATUS_FAIL)
    DEFINE_ECONSTANT(J_RESULT_STATUS_SUCCESS)
    return 0;
}
//=====================================================================================//
CONCEPT_DLL_API ON_DESTROY_CONTEXT MANAGEMENT_PARAMETERS {
    return 0;
}
//=====================================================================================//
static void status_recog_event(Recog *recog, void *delegate) {
    void *RES             = 0;
    void *EXCEPTION       = 0;

    if (delegate) {
        InvokePtr(INVOKE_CALL_DELEGATE, delegate, &RES, &EXCEPTION, (INTEGER)0);//, (INTEGER)VARIABLE_NUMBER, (char *)"", (double)(SYS_INT)0);
        if (EXCEPTION)
            InvokePtr(INVOKE_FREE_VARIABLE, EXCEPTION);
        if (RES) {
            INTEGER type  = 0;
            NUMBER  nData = 0;
            char    *str  = 0;

            InvokePtr(INVOKE_GET_VARIABLE, RES, &type, &str, &nData);
            if ((type == VARIABLE_NUMBER) && (nData == 1))
                j_request_terminate(recog);
            InvokePtr(INVOKE_FREE_VARIABLE, RES);
        }
    }
}

static AnsiString put_hypo_phoneme(WORD_ID *seq, int n, WORD_INFO *winfo) {
    int         i, j;
    WORD_ID     w;
    AnsiString  res;
    static char buf[MAX_HMMNAME_LEN];

    if (seq != NULL)
        for (i = 0; i < n; i++) {
            if (i > 0)
                res += (char *)" |";
            w = seq[i];
            for (j = 0; j < winfo->wlen[w]; j++) {
                if (j)
                    res += (char *)" ";
                center_name(winfo->wseq[w][j]->name, buf);
                res += buf;
            }
        }
    return res;
}

static void output_result(Recog *recog, void *delegate) {
    int          i, j;
    int          len;
    WORD_INFO    *winfo;
    WORD_ID      *seq;
    int          seqnum;
    int          n;
    Sentence     *s;
    RecogProcess *r;
    HMM_Logical  *p;

    INVOKE_CALL Invoke = InvokePtr;
    void *var = 0;
    CREATE_VARIABLE(var);
    CREATE_ARRAY(var);

    /* all recognition results are stored at each recognition process
     * instance */
    bool       has_data = false;

    INTEGER idx = 0;
    for (r = recog->process_list; r; r = r->next) {
        /* skip the process if the process is not alive */
        if (!r->live)
            continue;

        /* result are in r->result.  See recog.h for details */

        void *var2 = 0;
        Invoke(INVOKE_ARRAY_VARIABLE, var, (INTEGER)idx++, &var2);
        /* check result status */
        if (r->result.status < 0) {         /* no results obtained */
            /* outout message according to the status code */
            Invoke(INVOKE_SET_VARIABLE, var2, (INTEGER)VARIABLE_NUMBER, "", (NUMBER)r->result.status);
            continue;
        }

        /* output results for all the obtained sentences */
        winfo = r->lm->winfo;

        CREATE_ARRAY(var2);
        INTEGER idx2 = 0;
        for (n = 0; n < r->result.sentnum; n++) {         /* for all sentences */
            has_data = true;
            s        = &(r->result.sent[n]);
            seq      = s->word;
            seqnum   = s->word_num;
            if (!seqnum)
                continue;

            void *var3 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE, var2, (INTEGER)idx2++, &var3);
            CREATE_ARRAY(var3);

            void *var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, "s", &var4);
            CREATE_ARRAY(var4);

            /* output word sequence like Julius */
            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_STRING, winfo->woutput[seq[i]], (NUMBER)0);

            var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, "wsek", &var4);
            CREATE_ARRAY(var4);

            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_STRING, winfo->wname[seq[i]], (NUMBER)0);

            /* phoneme sequence */
            AnsiString phoneme(put_hypo_phoneme(seq, seqnum, winfo));
            if (phoneme.Length())
                Invoke(INVOKE_SET_ARRAY_ELEMENT_BY_KEY, var3, "phoneme", (INTEGER)VARIABLE_STRING, phoneme.c_str(), (NUMBER)phoneme.Length());

            var4 = 0;
            Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, var3, "score", &var4);
            CREATE_ARRAY(var4);

            /* confidence scores */
            for (i = 0; i < seqnum; i++)
                Invoke(INVOKE_SET_ARRAY_ELEMENT, var4, (INTEGER)i, (INTEGER)VARIABLE_NUMBER, "", (NUMBER)s->confidence[i]);
        }
    }
    if (delegate) {
        void *RES             = 0;
        void *EXCEPTION       = 0;

        INTEGER type  = 0;
        NUMBER  nData = 0;
        char    *str  = 0;

        InvokePtr(INVOKE_GET_VARIABLE, var, &type, &str, &nData);

        InvokePtr(INVOKE_CALL_DELEGATE, delegate, &RES, &EXCEPTION, (INTEGER)1, (INTEGER)type, str, nData);
        if (EXCEPTION)
            InvokePtr(INVOKE_FREE_VARIABLE, EXCEPTION);
        if (RES) {
            InvokePtr(INVOKE_GET_VARIABLE, RES, &type, &str, &nData);
            if ((type == VARIABLE_NUMBER) && (nData))
                j_request_terminate(recog);
            InvokePtr(INVOKE_FREE_VARIABLE, RES);
        }
    }
    FREE_VARIABLE(var);
}

CONCEPT_FUNCTION_IMPL_MINMAX_PARAMS(SpeechLoop, 1, 2)
    T_ARRAY("SpeechLoop", 0)
    int count = Invoke(INVOKE_GET_ARRAY_COUNT, PARAMETER(0));
    int argc = 1;
    char **argv = (char **)malloc((count * 2 + 1) * sizeof(char *));
    argv[0] = "SpeechLoop";
    bool has_mic = true;
    char *empty = (char *)"";
    void *on_result = 0;
    void *on_start = 0;
    void *on_stop = 0;
    void *on_ready = 0;
    void *on_recog_start = 0;
    void *on_recog_end = 0;
    char *stream = NULL;
    if (count > 0) {
        for (INTEGER i = 0; i < count; i++) {
            char *key = 0;
            Invoke(INVOKE_GET_ARRAY_KEY, PARAMETER(0), i, &key);
            INTEGER type  = 0;
            NUMBER  dummy = 0;
            char    *str  = 0;

            if (key) {
                Invoke(INVOKE_GET_ARRAY_ELEMENT_BY_KEY, PARAMETER(0), key, &type, &str, &dummy);
                if (strcmp(key, "OnResult") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_result);
                } else
                if (strcmp(key, "OnStart") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_start);
                } else
                if (strcmp(key, "OnStop") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_stop);
                } else
                if (strcmp(key, "OnReady") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_ready);
                } else
                if (strcmp(key, "OnRecognitionStart") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_recog_start);
                } else
                if (strcmp(key, "OnRecognitionEnd") == 0) {
                    if (type == VARIABLE_DELEGATE)
                        Invoke(INVOKE_ARRAY_VARIABLE_BY_KEY, PARAMETER(0), key, &on_recog_end);
                } else
                if (strcmp(key, "InputName") == 0) {
                    if (type == VARIABLE_STRING)
                        stream = str;
                } else
                if ((key) && (!strcmp(key, "j_adin_init"))) {
                    if (type == VARIABLE_NUMBER)
                        has_mic = (bool)(int)dummy;
                } else
                    argv[argc++] = key;
            } else
                Invoke(INVOKE_GET_ARRAY_ELEMENT, PARAMETER(0), i, &type, &str, &dummy);
            switch (type) {
                case VARIABLE_STRING:
                    if ((str) && (str[0]))
                        argv[argc++] = str;
                    else
                        argv[argc++] = empty;
                    break;
            }
        }
    }
    if (PARAMETERS_COUNT > 1) {
        SET_STRING(1, "");
    }

    Jconf *jconf = j_config_load_args_new(argc, argv);
    if (!jconf) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_config_load_args_new");
        }
        free(argv);
        RETURN_NUMBER(-1);
        return 0;
    }

    Recog *recog = j_create_instance_from_jconf(jconf);
    if (!recog) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_create_instance_from_jconf");
        }
        j_jconf_free(jconf);
        free(argv);
        RETURN_NUMBER(-2);
        return 0;
    }

    if ((has_mic) && (j_adin_init(recog) == FALSE)) {
        if (PARAMETERS_COUNT > 1) {
            SET_STRING(1, "j_adin_init");
        }
        // called by j_recog_free
        // j_jconf_free(jconf);
        j_recog_free(recog);
        free(argv);
        return 0;
    }

    if (on_ready) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_READY, status_recog_event, on_ready);
        Invoke(INVOKE_LOCK_VARIABLE, on_ready);
    }
    if (on_start) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_START, status_recog_event, on_start);
        Invoke(INVOKE_LOCK_VARIABLE, on_start);
    }
    if (on_stop) {
        callback_add(recog, CALLBACK_EVENT_SPEECH_STOP, status_recog_event, on_stop);
        Invoke(INVOKE_LOCK_VARIABLE, on_stop);
    }
    if (on_recog_start) {
        // callback_add(recog, CALLBACK_EVENT_RECOGNITION_START status_recog_event, on_recog_start);
        Invoke(INVOKE_LOCK_VARIABLE, on_recog_start);
    }
    if (on_recog_end) {
        // callback_add(recog, CALLBACK_EVENT_RECOGNITION_END, status_recog_event, on_recog_end);
        Invoke(INVOKE_LOCK_VARIABLE, on_recog_end);
    }

    if (on_result)
        callback_add(recog, CALLBACK_RESULT, output_result, on_result);

    bool stream_ok = false;
    switch (j_open_stream(recog, stream)) {
        case 0:
            stream_ok = true;
            break;

        case -1:
            if (PARAMETERS_COUNT > 1) {
                SET_STRING(1, "error in input stream");
            }
            break;

        case -2:
            if (PARAMETERS_COUNT > 1) {
                SET_STRING(1, "failed to begin input stream");
            }
            break;
    }

    int ret = -1;
    if (stream_ok)
        ret = j_recognize_stream(recog);
    // called by j_recog_free
    // if (jconf)
    //     j_jconf_free(jconf);
    if (stream_ok)
        j_close_stream(recog);
    j_recog_free(recog);
    free(argv);

    if (on_ready)
        Invoke(INVOKE_FREE_VARIABLE, on_ready);

    if (on_start)
        Invoke(INVOKE_FREE_VARIABLE, on_start);

    if (on_stop)
        Invoke(INVOKE_FREE_VARIABLE, on_stop);

    if (on_recog_start)
        Invoke(INVOKE_FREE_VARIABLE, on_recog_start);

    if (on_recog_end)
        Invoke(INVOKE_FREE_VARIABLE, on_recog_end);

    RETURN_NUMBER(0);
END_IMPL
//=====================================================================================//
<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */

#include <kroll/kroll.h>
#include <Poco/Environment.h>
#include <Poco/UUIDGenerator.h>
#include <Poco/Net/NetworkInterface.h>
#include <Poco/Net/IPAddress.h>
#include "platform_binding.h"

#ifdef OS_OSX
#include <Foundation/Foundation.h>
#elif defined(OS_WIN32)
#include <windows.h>
#include <Iptypes.h>
#include <Iphlpapi.h>
#elif defined(OS_LINUX)
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sstream>
#endif

#if defined(OS_OSX)
@interface NSProcessInfo (LegacyWarningSurpression)
- (unsigned int) processorCount;
//TODO: do the smart thing and test for it being NSUinteger
@end
#endif

namespace ti
{
	PlatformBinding::PlatformBinding(SharedBoundObject global) : global(global)
	{
		std::string os_name = Poco::Environment::osName();
		std::string os_version = Poco::Environment::osVersion();
		std::string arch = Poco::Environment::osArchitecture();
		std::string address = "127.0.0.1";

		std::vector<Poco::Net::NetworkInterface> list = Poco::Net::NetworkInterface::list();
		std::vector<Poco::Net::NetworkInterface>::iterator i = list.begin();
		SharedBoundList interfaces = new StaticBoundList();
		int c = 0;
		while (i!=list.end())
		{
			Poco::Net::NetworkInterface nitf = (*i++);
			if (nitf.supportsIPv4())
			{
				const Poco::Net::IPAddress ip = nitf.address();
				if (ip.isLoopback() || !ip.isIPv4Compatible())
				{
					continue;
				}
				c++;
				// just get the first one and bail
				if (c==1) address = ip.toString();
				// add each interface
				SharedBoundObject obj = new StaticBoundObject();
				std::string ip_addr = ip.toString();
				std::string display_name = nitf.displayName();
				std::string name = nitf.name();
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.address,since=0.2) ip address
				 */
				obj->Set("address",Value::NewString(ip_addr));
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.name,since=0.2) name of the interface
				 */
				obj->Set("name",Value::NewString(name));
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.displayName,since=0.2) display name of the interface
				 */
				obj->Set("displayName",Value::NewString(display_name));
				interfaces->Append(Value::NewObject(obj));
			}
		}
		/**
		 * @tiapi(method=True,type=list,name=Platform.interfaces,since=0.3) returns a list of network interfaces
		 */
		this->Set("interfaces", Value::NewList(interfaces));

#if defined(OS_OSX)
		int num_proc = 1;
		if ([NSProcessInfo instancesRespondToSelector:@selector(processorCount)]){
			num_proc = 	[[NSProcessInfo processInfo] processorCount];
		}
#elif defined(OS_WIN32)
		SYSTEM_INFO SysInfo ;
		GetSystemInfo (&SysInfo) ;
		DWORD num_proc = SysInfo.dwNumberOfProcessors;
#elif defined(OS_LINUX)
		int num_proc = sysconf(_SC_NPROCESSORS_ONLN);
#else
		int num_proc = 1;
#endif

		std::string machineid = FileUtils::GetMachineId();
		std::string macAddress = PlatformUtils::GetFirstMACAddress();

//NOTE: for now we determine this at compile time -- in the future
//we might want to actually programmatically determine if running on
//64-bit processor or not...
		/**
		 * @tiapi(property=True,type=string,name=Platform.ostype,since=0.3) the architecture type (either 32 bit or 64 bit)
		 */
#ifdef OS_32
		this->Set("ostype", Value::NewString("32bit"));
#else
		this->Set("ostype", Value::NewString("64bit"));
#endif
		/**
		 * @tiapi(property=True,type=string,name=Platform.name,since=0.2) the operating system name
		 */
		this->Set("name", Value::NewString(os_name));
		/**
		 * @tiapi(property=True,type=string,name=Platform.version,since=0.2) the operating system version
		 */
		this->Set("version", Value::NewString(os_version));
		/**
		 * @tiapi(property=True,type=string,name=Platform.architecture,since=0.2) the operating system architecture
		 */
		this->Set("architecture", Value::NewString(arch));
		/**
		 * @tiapi(property=True,type=string,name=Platform.address,since=0.2) the primary ip address
		 */
		this->Set("address", Value::NewString(address));
		/**
		 * @tiapi(property=True,type=string,name=Platform.id,since=0.2) the unique machine id
		 */
		this->Set("id", Value::NewString(machineid));
		/**
		 * @tiapi(property=True,type=string,name=Platform.macaddress,since=0.3) the primary mac address
		 */
		this->Set("macaddress", Value::NewString(macAddress));
		/**
		 * @tiapi(property=True,type=integer,name=Platform.processorCount,since=0.2) the number of processors for the machine
		 */
		this->Set("processorCount", Value::NewInt(num_proc));
		std::string username = kroll::FileUtils::GetUsername();
		/**
		 * @tiapi(property=True,type=string,name=Platform.username,since=0.2) the platform's user name
		 */
		this->Set("username", Value::NewString(username));

		// UUID create function for the platform
		/**
		 * @tiapi(method=True,returns=string,name=Platform.createUUID,since=0.3) create a globally unique id
		 * @tiresult(for=Platform.createUUID,type=string) result as string
		 */
		this->SetMethod("createUUID",&PlatformBinding::CreateUUID);
	}

	PlatformBinding::~PlatformBinding()
	{
	}

	void PlatformBinding::CreateUUID(const ValueList& args, SharedValue result)
	{
		Poco::UUID uuid = Poco::UUIDGenerator::defaultGenerator().createRandom();
		result->SetString(uuid.toString().c_str());
	}
}
<commit_msg>use PlatformBinding::GetMachineId<commit_after>/**
 * Appcelerator Titanium - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2009 Appcelerator, Inc. All Rights Reserved.
 */

#include <kroll/kroll.h>
#include <Poco/Environment.h>
#include <Poco/UUIDGenerator.h>
#include <Poco/Net/NetworkInterface.h>
#include <Poco/Net/IPAddress.h>
#include "platform_binding.h"

#ifdef OS_OSX
#include <Foundation/Foundation.h>
#elif defined(OS_WIN32)
#include <windows.h>
#include <Iptypes.h>
#include <Iphlpapi.h>
#elif defined(OS_LINUX)
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sstream>
#endif

#if defined(OS_OSX)
@interface NSProcessInfo (LegacyWarningSurpression)
- (unsigned int) processorCount;
//TODO: do the smart thing and test for it being NSUinteger
@end
#endif

namespace ti
{
	PlatformBinding::PlatformBinding(SharedBoundObject global) : global(global)
	{
		std::string os_name = Poco::Environment::osName();
		std::string os_version = Poco::Environment::osVersion();
		std::string arch = Poco::Environment::osArchitecture();
		std::string address = "127.0.0.1";

		std::vector<Poco::Net::NetworkInterface> list = Poco::Net::NetworkInterface::list();
		std::vector<Poco::Net::NetworkInterface>::iterator i = list.begin();
		SharedBoundList interfaces = new StaticBoundList();
		int c = 0;
		while (i!=list.end())
		{
			Poco::Net::NetworkInterface nitf = (*i++);
			if (nitf.supportsIPv4())
			{
				const Poco::Net::IPAddress ip = nitf.address();
				if (ip.isLoopback() || !ip.isIPv4Compatible())
				{
					continue;
				}
				c++;
				// just get the first one and bail
				if (c==1) address = ip.toString();
				// add each interface
				SharedBoundObject obj = new StaticBoundObject();
				std::string ip_addr = ip.toString();
				std::string display_name = nitf.displayName();
				std::string name = nitf.name();
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.address,since=0.2) ip address
				 */
				obj->Set("address",Value::NewString(ip_addr));
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.name,since=0.2) name of the interface
				 */
				obj->Set("name",Value::NewString(name));
				/**
				 * @tiapi(property=True,type=string,name=Platform.Interface.displayName,since=0.2) display name of the interface
				 */
				obj->Set("displayName",Value::NewString(display_name));
				interfaces->Append(Value::NewObject(obj));
			}
		}
		/**
		 * @tiapi(method=True,type=list,name=Platform.interfaces,since=0.3) returns a list of network interfaces
		 */
		this->Set("interfaces", Value::NewList(interfaces));

#if defined(OS_OSX)
		int num_proc = 1;
		if ([NSProcessInfo instancesRespondToSelector:@selector(processorCount)]){
			num_proc = 	[[NSProcessInfo processInfo] processorCount];
		}
#elif defined(OS_WIN32)
		SYSTEM_INFO SysInfo ;
		GetSystemInfo (&SysInfo) ;
		DWORD num_proc = SysInfo.dwNumberOfProcessors;
#elif defined(OS_LINUX)
		int num_proc = sysconf(_SC_NPROCESSORS_ONLN);
#else
		int num_proc = 1;
#endif

		std::string machineid = PlatformUtils::GetMachineId();
		std::string macAddress = PlatformUtils::GetFirstMACAddress();

//NOTE: for now we determine this at compile time -- in the future
//we might want to actually programmatically determine if running on
//64-bit processor or not...
		/**
		 * @tiapi(property=True,type=string,name=Platform.ostype,since=0.3) the architecture type (either 32 bit or 64 bit)
		 */
#ifdef OS_32
		this->Set("ostype", Value::NewString("32bit"));
#else
		this->Set("ostype", Value::NewString("64bit"));
#endif
		/**
		 * @tiapi(property=True,type=string,name=Platform.name,since=0.2) the operating system name
		 */
		this->Set("name", Value::NewString(os_name));
		/**
		 * @tiapi(property=True,type=string,name=Platform.version,since=0.2) the operating system version
		 */
		this->Set("version", Value::NewString(os_version));
		/**
		 * @tiapi(property=True,type=string,name=Platform.architecture,since=0.2) the operating system architecture
		 */
		this->Set("architecture", Value::NewString(arch));
		/**
		 * @tiapi(property=True,type=string,name=Platform.address,since=0.2) the primary ip address
		 */
		this->Set("address", Value::NewString(address));
		/**
		 * @tiapi(property=True,type=string,name=Platform.id,since=0.2) the unique machine id
		 */
		this->Set("id", Value::NewString(machineid));
		/**
		 * @tiapi(property=True,type=string,name=Platform.macaddress,since=0.3) the primary mac address
		 */
		this->Set("macaddress", Value::NewString(macAddress));
		/**
		 * @tiapi(property=True,type=integer,name=Platform.processorCount,since=0.2) the number of processors for the machine
		 */
		this->Set("processorCount", Value::NewInt(num_proc));
		std::string username = kroll::FileUtils::GetUsername();
		/**
		 * @tiapi(property=True,type=string,name=Platform.username,since=0.2) the platform's user name
		 */
		this->Set("username", Value::NewString(username));

		// UUID create function for the platform
		/**
		 * @tiapi(method=True,returns=string,name=Platform.createUUID,since=0.3) create a globally unique id
		 * @tiresult(for=Platform.createUUID,type=string) result as string
		 */
		this->SetMethod("createUUID",&PlatformBinding::CreateUUID);
	}

	PlatformBinding::~PlatformBinding()
	{
	}

	void PlatformBinding::CreateUUID(const ValueList& args, SharedValue result)
	{
		Poco::UUID uuid = Poco::UUIDGenerator::defaultGenerator().createRandom();
		result->SetString(uuid.toString().c_str());
	}
}
<|endoftext|>


<commit_before>#include "chainerx/native/native_device.h"

#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/reduction.h"
#include "chainerx/kernels/sorting.h"
#include "chainerx/macro.h"
#include "chainerx/native/data_type.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/native/reduce.h"
#include "chainerx/numeric.h"
#include "chainerx/numeric_limits.h"
#include "chainerx/shape.h"

namespace chainerx {
namespace native {
namespace {

class NativeArgMaxKernel : public ArgMaxKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MaxAndArgMax {
                    T max;
                    int64_t argmax;
                };

                MaxAndArgMax Identity() { return {T{}, -1}; }
                MaxAndArgMax MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MaxAndArgMax next, MaxAndArgMax& accum) {
                    if (accum.argmax < 0 || accum.max < next.max) {
                        accum = next;
                    }
                }
                int64_t MapOut(MaxAndArgMax accum) { return accum.argmax; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMaxKernel, NativeArgMaxKernel);

class NativeArgMinKernel : public ArgMinKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MinAndArgMin {
                    T min;
                    int64_t argmin;
                };

                MinAndArgMin Identity() { return {T{}, -1}; }
                MinAndArgMin MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MinAndArgMin next, MinAndArgMin& accum) {
                    if (accum.argmin < 0 || accum.min > next.min) {
                        accum = next;
                    }
                }
                int64_t MapOut(MinAndArgMin accum) { return accum.argmin; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMinKernel, NativeArgMinKernel);

class NativeSumKernel : public SumKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), true));
        a.device().CheckDevicesCompatible(a, out);

        auto do_sum = [&a, &axis, &out](auto in_pt, auto out_pt) {
            using In = typename decltype(in_pt)::type;
            using Out = typename decltype(out_pt)::type;
            using Accum = std::conditional_t<std::is_same<Out, Float16>{}, float, Out>;
            struct Impl {
                Accum Identity() { return Accum{0}; }
                Accum MapIn(In in, int64_t /*index*/) { return static_cast<Accum>(in); }
                void Reduce(Accum next, Accum& accum) { accum += next; }
                Out MapOut(Accum accum) { return static_cast<Out>(accum); }
            };
            Reduce<In, Out>(a, axis, out, Impl{});
        };

        VisitDtype(out.dtype(), [a_dtype = a.dtype(), &do_sum](auto out_pt) { VisitDtype(a_dtype, do_sum, out_pt); });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SumKernel, NativeSumKernel);

class NativeCumsumKernel : public CumsumKernel {
public:
    void Call(const Array& a, int8_t axis, const Array& out) override {
        a.device().CheckDevicesCompatible(a, out);
        const Array& a_cast = a.dtype() != out.dtype() ? a.AsType(out.dtype()) : a;

        VisitDtype(out.dtype(), [&a_cast, axis, &out](auto pt) {
            using T = typename decltype(pt)::type;

            IndexableArray<const T> a_iarray{a_cast};
            IndexableArray<T> out_iarray{out};
            Indexer<> out_indexer{out.shape()};
            Indexer<> prev_indexer{a_cast.shape()};

            int64_t axis_dim = a_cast.shape()[axis];

            // left: set of input dimensions lower than the axis
            // right: set of input dimensions higher than the axis
            Shape left_shape{a_cast.shape().begin(), a_cast.shape().begin() + axis};
            Shape right_shape{a_cast.shape().begin() + (axis + 1), a_cast.shape().end()};
            Shape axis_shape{axis_dim};  // always ndim==1

            Indexer<> left_indexer{left_shape};
            Indexer<> right_indexer{right_shape};
            Indexer<> indices_indexer{axis_shape};

            auto it_left = left_indexer.It(0);
            auto it_right = right_indexer.It(0);
            auto it_out = out_indexer.It(0);
            auto it_prev = prev_indexer.It(0);

            // Copy
            for (auto it = out_indexer.It(0); it; ++it) {
                out_iarray[it] = a_iarray[it];
            }

            for (auto it = indices_indexer.It(1); it; ++it) {
                int64_t index = it.raw_index();
                index = index % axis_dim;
                CHAINERX_ASSERT(0 <= index);
                CHAINERX_ASSERT(index < axis_dim);

                it_out.CopyIndex(it, it_left.ndim());

                for (it_left.Restart(); it_left; ++it_left) {
                    it_out.CopyIndex(it_left);

                    for (it_right.Restart(); it_right; ++it_right) {
                        it_out.CopyIndex(it_right, it_left.ndim() + it.ndim());
                        it_prev.CopyIndex(it_out);
                        it_prev.index()[axis] -= 1;
                        native_internal::StorageToDataType<T>(out_iarray[it_out]) +=
                                native_internal::StorageToDataType<T>(out_iarray[it_prev]);
                        it_prev.index()[axis] += 1;
                    }
                }
            }
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CumsumKernel, NativeCumsumKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<commit_msg>Add TODO<commit_after>#include "chainerx/native/native_device.h"

#include <cstdint>

#include "chainerx/array.h"
#include "chainerx/axes.h"
#include "chainerx/device.h"
#include "chainerx/dtype.h"
#include "chainerx/kernels/reduction.h"
#include "chainerx/kernels/sorting.h"
#include "chainerx/macro.h"
#include "chainerx/native/data_type.h"
#include "chainerx/native/kernel_regist.h"
#include "chainerx/native/reduce.h"
#include "chainerx/numeric.h"
#include "chainerx/numeric_limits.h"
#include "chainerx/shape.h"

namespace chainerx {
namespace native {
namespace {

class NativeArgMaxKernel : public ArgMaxKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MaxAndArgMax {
                    T max;
                    int64_t argmax;
                };

                MaxAndArgMax Identity() { return {T{}, -1}; }
                MaxAndArgMax MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MaxAndArgMax next, MaxAndArgMax& accum) {
                    if (accum.argmax < 0 || accum.max < next.max) {
                        accum = next;
                    }
                }
                int64_t MapOut(MaxAndArgMax accum) { return accum.argmax; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMaxKernel, NativeArgMaxKernel);

class NativeArgMinKernel : public ArgMinKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(std::all_of(axis.begin(), axis.end(), [&a](int8_t i) { return a.shape()[i] > 0; }));
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), false));
        a.device().CheckDevicesCompatible(a, out);

        VisitDtype(a.dtype(), [&a, &axis, &out](auto pt) {
            using T = typename decltype(pt)::type;
            struct Impl {
                struct MinAndArgMin {
                    T min;
                    int64_t argmin;
                };

                MinAndArgMin Identity() { return {T{}, -1}; }
                MinAndArgMin MapIn(T in, int64_t index) { return {in, index}; }
                void Reduce(MinAndArgMin next, MinAndArgMin& accum) {
                    if (accum.argmin < 0 || accum.min > next.min) {
                        accum = next;
                    }
                }
                int64_t MapOut(MinAndArgMin accum) { return accum.argmin; }
            };
            Reduce<T, int64_t>(a, axis, out, Impl{});
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(ArgMinKernel, NativeArgMinKernel);

class NativeSumKernel : public SumKernel {
public:
    void Call(const Array& a, const Axes& axis, const Array& out) override {
        CHAINERX_ASSERT(internal::IsValidReductionShape(a.shape(), axis, out.shape(), true));
        a.device().CheckDevicesCompatible(a, out);

        auto do_sum = [&a, &axis, &out](auto in_pt, auto out_pt) {
            using In = typename decltype(in_pt)::type;
            using Out = typename decltype(out_pt)::type;
            using Accum = std::conditional_t<std::is_same<Out, Float16>{}, float, Out>;
            struct Impl {
                Accum Identity() { return Accum{0}; }
                Accum MapIn(In in, int64_t /*index*/) { return static_cast<Accum>(in); }
                void Reduce(Accum next, Accum& accum) { accum += next; }
                Out MapOut(Accum accum) { return static_cast<Out>(accum); }
            };
            Reduce<In, Out>(a, axis, out, Impl{});
        };

        VisitDtype(out.dtype(), [a_dtype = a.dtype(), &do_sum](auto out_pt) { VisitDtype(a_dtype, do_sum, out_pt); });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(SumKernel, NativeSumKernel);

class NativeCumsumKernel : public CumsumKernel {
// TODO(imanishi): Performance improvement.
public:
    void Call(const Array& a, int8_t axis, const Array& out) override {
        a.device().CheckDevicesCompatible(a, out);
        const Array& a_cast = a.dtype() != out.dtype() ? a.AsType(out.dtype()) : a;

        VisitDtype(out.dtype(), [&a_cast, axis, &out](auto pt) {
            using T = typename decltype(pt)::type;

            IndexableArray<const T> a_iarray{a_cast};
            IndexableArray<T> out_iarray{out};
            Indexer<> out_indexer{out.shape()};
            Indexer<> prev_indexer{a_cast.shape()};

            int64_t axis_dim = a_cast.shape()[axis];

            // left: set of input dimensions lower than the axis
            // right: set of input dimensions higher than the axis
            Shape left_shape{a_cast.shape().begin(), a_cast.shape().begin() + axis};
            Shape right_shape{a_cast.shape().begin() + (axis + 1), a_cast.shape().end()};
            Shape axis_shape{axis_dim};  // always ndim==1

            Indexer<> left_indexer{left_shape};
            Indexer<> right_indexer{right_shape};
            Indexer<> indices_indexer{axis_shape};

            auto it_left = left_indexer.It(0);
            auto it_right = right_indexer.It(0);
            auto it_out = out_indexer.It(0);
            auto it_prev = prev_indexer.It(0);

            // Copy
            for (auto it = out_indexer.It(0); it; ++it) {
                out_iarray[it] = a_iarray[it];
            }

            for (auto it = indices_indexer.It(1); it; ++it) {
                int64_t index = it.raw_index();
                index = index % axis_dim;
                CHAINERX_ASSERT(0 <= index);
                CHAINERX_ASSERT(index < axis_dim);

                it_out.CopyIndex(it, it_left.ndim());

                for (it_left.Restart(); it_left; ++it_left) {
                    it_out.CopyIndex(it_left);

                    for (it_right.Restart(); it_right; ++it_right) {
                        it_out.CopyIndex(it_right, it_left.ndim() + it.ndim());
                        it_prev.CopyIndex(it_out);
                        it_prev.index()[axis] -= 1;
                        native_internal::StorageToDataType<T>(out_iarray[it_out]) +=
                                native_internal::StorageToDataType<T>(out_iarray[it_prev]);
                        it_prev.index()[axis] += 1;
                    }
                }
            }
        });
    }
};

CHAINERX_NATIVE_REGISTER_KERNEL(CumsumKernel, NativeCumsumKernel);

}  // namespace
}  // namespace native
}  // namespace chainerx
<|endoftext|>


<commit_before>#include <Game/Player/cPlayer.h>
#include <Collision/cAABBCollider.h>
#include <Game/cFieldManager.h>
#include <CameraManager/cCameraManager.h>
#include <Resource/cObjectManager.h>
#include <Resource/TextureManager.h>

void Game::Player::cPlayer::playerRotation()
{
	//vC[̑O
	ci::vec3 rotateaxis = ci::vec3(0.0f, 0.0f, 1.0f);
	//ړ̃xNg
	ci::vec3 targetvec = ci::vec3(velocity.x, 0, velocity.z);

	//ړnormalize
	targetvec = ci::normalize(targetvec);
	if (velocity.x >= 0.01f ||
		velocity.x <= -0.01f ||
		velocity.z >= 0.01f ||
		velocity.z <= -0.01f )
		installation_position = ci::vec3(velocity.x * 10, 0, velocity.z * 10);

	//]
	ci::vec3 quataxis = glm::cross(rotateaxis, targetvec);

	float rotation = atan2f(velocity.x, velocity.z);

	//]
	//
	if (rotation > 0.1f) {
		ci::gl::rotate(rotation, quataxis);
		save_rotate = rotation;
	}
	// E
	else if (rotation < -0.1f) {
		ci::gl::rotate(-rotation, quataxis);
		save_rotate = rotation;
	}

	//xNgoȂ
	if (rotation <= 0.1f &&
		rotation >= -0.1f) {
		if (save_rotate > 0.1f)
			ci::gl::rotate(save_rotate, ci::vec3(0, 1, 0));
		if (save_rotate < -0.1f)
			ci::gl::rotate(save_rotate, ci::vec3(0, 1, 0));
	}

}

//RXgN^
//ʒuƊpxƉPƂǂꂪ̃vC[
//炤
Game::Player::cPlayer::cPlayer(
	const ci::vec3& pos,
	const int& id,
	const bool& is_active_user,
	const Game::Player::Team& team)
	: cObjectBase(pos),
	mCollider(mPos, ci::vec3(0.8f, 0.8f, 0.8f)),
	mRigidbody(mCollider)
{
	size = ci::vec3(1);
	color = ci::vec4(1);
	color = ci::ColorA8u(1, 0, 1, 1);
	velocity = ci::vec3(0);
	this->team = team;
	save_rotate = 0;
	drilling = false;
	jump_flag = false;

	//vC[̃Xe[^X
	status.attack = 10;
	status.drill_range = 1;
	status.jump_force = 0.6F;
	status.speed = DEFAULT_SPEED;
	//ݒuʒu
	installation_position = ci::vec3(0,0,2);

	player_id = id;
	active_user = is_active_user;
}

void Game::Player::cPlayer::move(const ci::vec3 & velocity)
{

	auto speed = mRigidbody.getSpeed() - this->velocity;

	//vC[̈ړxNgۑ
	this->velocity = velocity;

	mRigidbody.setSpeed(ci::vec3(0,speed.y,0) + velocity);
	//vC[̈ړ
	mPos = mCollider.getPosition();

}

void Game::Player::cPlayer::jump(bool flag)
{
	if(jump_flag == false)
	jump_flag = flag;

	if (jump_flag == true) {
		if (mRigidbody.isLanding()) {
			velocity.y = -status.jump_force;
			jump_flag = false;
		}
	}
}

void Game::Player::cPlayer::setup()
{
    mCollider.setLayer( 1 << 0 );
	mCollider.addWorld();
	mRigidbody.addWorld();
	//ȊO͒ʐMňʒuĂ̂
	//d͂KvȂ
	if (!active_user)mRigidbody.gravityOff();

	mesh = Resource::cObjectManager::getInstance()->findObject("montamogura/moguraHontai.obj");
	TEX->set("mogura", "OBJ/montamogura/moguraHontai.png");
}

#include <Game/cClientAdapter.h>
void Game::Player::cPlayer::update(const float & delta_time)
{
	if (drilling) {
		Game::cFieldManager::getInstance()->blockBreak(mCollider.getPosition() + ci::vec3(0, -1,0), 1);
	}
}

void Game::Player::cPlayer::draw()
{
    ci::gl::ScopedColor col( color );
    ci::gl::ScopedTextureBind tex( TEX->get( "mogura" ) );
    ci::gl::ScopedGlslProg glsl( ci::gl::getStockShader( ci::gl::ShaderDef( ).texture( ) ) );

	ci::gl::pushModelView();
	ci::gl::translate(mPos - ci::vec3(0, 0.5f, 0));
	playerRotation();
	ci::gl::scale(ci::vec3(0.01f, 0.01f, 0.012f));
	ci::gl::draw(mesh);
	ci::gl::popModelView();
}
<commit_msg>クォータニオンバグ修正<commit_after>#include <Game/Player/cPlayer.h>
#include <Collision/cAABBCollider.h>
#include <Game/cFieldManager.h>
#include <CameraManager/cCameraManager.h>
#include <Resource/cObjectManager.h>
#include <Resource/TextureManager.h>

void Game::Player::cPlayer::playerRotation()
{
	//vC[̑O
	ci::vec3 rotateaxis = ci::vec3(0.0f, 0.0f, 1.0f);
	//ړ̃xNg
	ci::vec3 targetvec = ci::vec3(velocity.x, 0, velocity.z);

	//ړnormalize
	targetvec = ci::normalize(targetvec);
	if (velocity.x >= 0.01f ||
		velocity.x <= -0.01f ||
		velocity.z >= 0.01f ||
		velocity.z <= -0.01f )
		installation_position = ci::vec3(velocity.x * 10, 0, velocity.z * 10);

	//]
	ci::vec3 quataxis = glm::cross(rotateaxis, targetvec);

	//xNgԂƃNH[^jI
	//OɂȂB
	//ŏ̃xNgƂ̊OςĂ̂ŁAO
	//ɂȂ̂ZƕsȃxNg̎B
	//Ȃ̂ZO̎ƂP̎OƂĊpx
	//^Ȃ΂ȂȂ
	if (quataxis == ci::vec3(0)) {
		if (velocity.z > 0.0f) {
			ci::gl::rotate(0, ci::vec3(0, 1, 0));
			save_rotate = 0;
		}
		if (velocity.z < 0.0f) {
			ci::gl::rotate(M_PI, ci::vec3(0, 1, 0));
			save_rotate = M_PI;
		}

		return;
	}

	float rotation = atan2f(velocity.x, velocity.z);

	//]
	//
	if (rotation > 0.1f) {
		ci::gl::rotate(rotation, quataxis);
		save_rotate = rotation;
	}
	// E
	else if (rotation < -0.1f) {
		ci::gl::rotate(-rotation, quataxis);
		save_rotate = rotation;
	}

	//xNgoȂ
	if (rotation <= 0.1f &&
		rotation >= -0.1f) {
		if (save_rotate > 0.1f)
			ci::gl::rotate(save_rotate, ci::vec3(0, 1, 0));
		if (save_rotate < -0.1f)
			ci::gl::rotate(save_rotate, ci::vec3(0, 1, 0));
	}

}

//RXgN^
//ʒuƊpxƉPƂǂꂪ̃vC[
//炤
Game::Player::cPlayer::cPlayer(
	const ci::vec3& pos,
	const int& id,
	const bool& is_active_user,
	const Game::Player::Team& team)
	: cObjectBase(pos),
	mCollider(mPos, ci::vec3(0.8f, 0.8f, 0.8f)),
	mRigidbody(mCollider)
{
	size = ci::vec3(1);
	color = ci::vec4(1);
	color = ci::ColorA8u(1, 0, 1, 1);
	velocity = ci::vec3(0);
	this->team = team;
	save_rotate = 0;
	drilling = false;
	jump_flag = false;

	//vC[̃Xe[^X
	status.attack = 10;
	status.drill_range = 1;
	status.jump_force = 0.6F;
	status.speed = DEFAULT_SPEED;
	//ݒuʒu
	installation_position = ci::vec3(0,0,2);

	player_id = id;
	active_user = is_active_user;
}

void Game::Player::cPlayer::move(const ci::vec3 & velocity)
{

	auto speed = mRigidbody.getSpeed() - this->velocity;

	//vC[̈ړxNgۑ
	this->velocity = velocity;

	mRigidbody.setSpeed(ci::vec3(0,speed.y,0) + velocity);
	//vC[̈ړ
	mPos = mCollider.getPosition();

}

void Game::Player::cPlayer::jump(bool flag)
{
	if(jump_flag == false)
	jump_flag = flag;

	if (jump_flag == true) {
		if (mRigidbody.isLanding()) {
			velocity.y = -status.jump_force;
			jump_flag = false;
		}
	}
}

void Game::Player::cPlayer::setup()
{
    mCollider.setLayer( 1 << 0 );
	mCollider.addWorld();
	mRigidbody.addWorld();
	//ȊO͒ʐMňʒuĂ̂
	//d͂KvȂ
	if (!active_user)mRigidbody.gravityOff();

	mesh = Resource::cObjectManager::getInstance()->findObject("montamogura/moguraHontai.obj");
	TEX->set("mogura", "OBJ/montamogura/moguraHontai.png");
}

#include <Game/cClientAdapter.h>
void Game::Player::cPlayer::update(const float & delta_time)
{
	if (drilling) {
		Game::cFieldManager::getInstance()->blockBreak(mCollider.getPosition() + ci::vec3(0, -1,0), 1);
	}
}

void Game::Player::cPlayer::draw()
{
    ci::gl::ScopedColor col( color );
    ci::gl::ScopedTextureBind tex( TEX->get( "mogura" ) );
    ci::gl::ScopedGlslProg glsl( ci::gl::getStockShader( ci::gl::ShaderDef( ).texture( ) ) );

	ci::gl::pushModelView();
	ci::gl::translate(mPos - ci::vec3(0, 0.5f, 0));
	playerRotation();
	ci::gl::scale(ci::vec3(0.01f, 0.01f, 0.012f));
	ci::gl::draw(mesh);
	ci::gl::popModelView();
}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <cstdint>
#include <array>

int main()
{
  std::array<int32_t, 10> arr;
  printf("%p\n", static_cast<void*>(arr.data() + arr.size()));
  return EXIT_SUCCESS;
}
<commit_msg>out_of_bounds_pointer is not arr.end()<commit_after>#include <cstdlib>
#include <cstdint>
#include <array>

int main()
{
  std::array<int32_t, 10> arr;
  printf("%p\n", static_cast<void*>(arr.data() - 1));
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <osg/GL>
#include <osg/GLU>

#include <osg/Notify>
#include <osgUtil/Tesselator>

using namespace osg;
using namespace osgUtil;

static Tesselator* s_currentTesselator=0;

Tesselator::Tesselator()
{
    _tobj = 0;
    _errorCode = 0;
}

Tesselator::~Tesselator()
{
    if (_tobj) gluDeleteTess(_tobj);
}

void Tesselator::beginTesselation()
{
    reset();

    if (!_tobj) _tobj = gluNewTess();

    gluTessCallback(_tobj, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK*)()) vertexCallback);
    gluTessCallback(_tobj, GLU_TESS_BEGIN_DATA,  (GLvoid (CALLBACK*)()) beginCallback);
    gluTessCallback(_tobj, GLU_TESS_END_DATA,    (GLvoid (CALLBACK*)()) endCallback);
    gluTessCallback(_tobj, GLU_TESS_COMBINE,     (GLvoid (CALLBACK*)()) combineCallback);
    gluTessCallback(_tobj, GLU_TESS_ERROR_DATA,  (GLvoid (CALLBACK*)()) errorCallback);

    gluTessBeginPolygon(_tobj,this);

    s_currentTesselator = this;

}

void Tesselator::beginContour()
{
    if (_tobj)
    {
        gluTessBeginContour(_tobj);
    }
}

void Tesselator::addVertex(osg::Vec3* vertex)
{
    if (_tobj)
    {
        Vec3d* data = new Vec3d;
        _coordData.push_back(data);
        (*data)._v[0]=(*vertex)[0];
        (*data)._v[1]=(*vertex)[1];
        (*data)._v[2]=(*vertex)[2];
        gluTessVertex(_tobj,data->_v,vertex);
    }
}

void Tesselator::endContour()
{
    if (_tobj)
    {
        gluTessEndContour(_tobj);
    }
}

void Tesselator::endTesselation()
{
    if (_tobj)
    {
        gluTessEndPolygon(_tobj);
        gluDeleteTess(_tobj);
        _tobj = 0;

        if (_errorCode!=0)
        {
           const GLubyte *estring = gluErrorString((GLenum)_errorCode);
           osg::notify(osg::WARN)<<"Tessellation Error: "<<estring<< std::endl;
        }
    }
}

void Tesselator::reset()
{
    if (_tobj)
    {
        gluDeleteTess(_tobj);
        _tobj = 0;
    }
    _primList.clear();
    _coordData.clear();
    _newVertexList.clear();
    _errorCode = 0;
}

class InsertNewVertices : public osg::ArrayVisitor
{
    public:

        float _f1,_f2,_f3,_f4;
        unsigned int _i1,_i2,_i3,_i4;

        InsertNewVertices(float f1,unsigned int i1,
                          float f2,unsigned int i2,
                          float f3,unsigned int i3,
                          float f4,unsigned int i4):
                            _f1(f1),_f2(f2),_f3(f3),_f4(f4),
                            _i1(i1),_i2(i2),_i3(i3),_i4(i4){}

        template <class A,class Type>
        void apply_imp(A& array)
        {
            Type val;
            if (_f1) val += static_cast<Type>(array[_i1] * _f1);
            if (_f2) val += static_cast<Type>(array[_i2] * _f2);
            if (_f3) val += static_cast<Type>(array[_i3] * _f3);
            if (_f4) val += static_cast<Type>(array[_i4] * _f4);

            array.push_back(val);
        }

        virtual void apply(osg::ByteArray& ba) { apply_imp<ByteArray,ByteArray::value_type>(ba); }
        virtual void apply(osg::ShortArray& ba) { apply_imp<ShortArray,ShortArray::value_type>(ba); }
        virtual void apply(osg::IntArray& ba) { apply_imp<IntArray,IntArray::value_type>(ba); }
        virtual void apply(osg::UByteArray& ba) { apply_imp<UByteArray,UByteArray::value_type>(ba); }
        virtual void apply(osg::UShortArray& ba) { apply_imp<UShortArray,UShortArray::value_type>(ba); }
        virtual void apply(osg::UIntArray& ba) { apply_imp<UIntArray,UIntArray::value_type>(ba); }
        virtual void apply(osg::UByte4Array& ba) { apply_imp<UByte4Array,UByte4Array::value_type>(ba); }
        virtual void apply(osg::FloatArray& ba) { apply_imp<FloatArray,FloatArray::value_type>(ba); }
        virtual void apply(osg::Vec2Array& ba) { apply_imp<Vec2Array,Vec2Array::value_type>(ba); }
        virtual void apply(osg::Vec3Array& ba) { apply_imp<Vec3Array,Vec3Array::value_type>(ba); }
        virtual void apply(osg::Vec4Array& ba) { apply_imp<Vec4Array,Vec4Array::value_type>(ba); }

};

void Tesselator::retesselatePolygons(osg::Geometry& geom)
{
    Vec3Array* vertices = geom.getVertexArray();
    if (!vertices || vertices->empty() || geom.getPrimitiveList().empty()) return;

    int noPrimitiveAtStart = geom.getPrimitiveList().size();
    for(int primNo=0;primNo<noPrimitiveAtStart;++primNo)
    {
        osg::Primitive* primitive = geom.getPrimitiveList()[primNo].get();
        if (primitive->getMode()==osg::Primitive::POLYGON)
        {
            beginTesselation();
            beginContour();

            switch(primitive->getType())
            {
                case(osg::Primitive::DrawArraysPrimitiveType):
                {
                    osg::DrawArrays* drawArray = static_cast<osg::DrawArrays*>(primitive);
                    unsigned int first = drawArray->getFirst();
                    unsigned int last = first+drawArray->getCount();
                    for(unsigned int i=first;i<last;++i)
                    {
                        addVertex(&((*vertices)[i]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUBytePrimitiveType):
                {
                    osg::DrawElementsUByte* drawElements = static_cast<osg::DrawElementsUByte*>(primitive);
                    for(osg::DrawElementsUByte::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUShortPrimitiveType):
                {
                    osg::DrawElementsUShort* drawElements = static_cast<osg::DrawElementsUShort*>(primitive);
                    for(osg::DrawElementsUShort::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUIntPrimitiveType):
                {
                    osg::DrawElementsUInt* drawElements = static_cast<osg::DrawElementsUInt*>(primitive);
                    for(osg::DrawElementsUInt::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                default:
                    break;
            }

            endContour();
            endTesselation();

            typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
            VertexPtrToIndexMap vertexPtrToIndexMap;

            // populate the VertexPtrToIndexMap.
            for(unsigned int vi=0;vi<vertices->size();++vi)
            {
                vertexPtrToIndexMap[&((*vertices)[vi])] = vi;
            }

            if (!_newVertexList.empty())
            {

                osg::Vec3Array* normals = NULL;
                if (geom.getNormalBinding()==osg::Geometry::BIND_PER_VERTEX)
                {
                    normals = geom.getNormalArray();
                }

                typedef std::vector<osg::Array*> ArrayList;
                ArrayList arrays;

                if (geom.getColorBinding()==osg::Geometry::BIND_PER_VERTEX)
                {
                    arrays.push_back(geom.getColorArray());
                }

                osg::Geometry::TexCoordArrayList& tcal = geom.getTexCoordArrayList();
                for(osg::Geometry::TexCoordArrayList::iterator tcalItr=tcal.begin();
                    tcalItr!=tcal.end();
                    ++tcalItr)
                {
                    if (tcalItr->valid())
                    {
                        arrays.push_back(tcalItr->get());
                    }
                }

                // now add any new vertices that are required.
                for(NewVertexList::iterator itr=_newVertexList.begin();
                    itr!=_newVertexList.end();
                    ++itr)
                {
                    osg::Vec3* vertex = itr->first;
                    NewVertex& newVertex = itr->second;

                    // assign vertex.
                    vertexPtrToIndexMap[vertex]=vertices->size();
                    vertices->push_back(*vertex);

                    // assign normals
                    if (normals)
                    {
                        osg::Vec3 norm(0.0f,0.0f,0.0f);
                        if (newVertex._v1) norm += (*normals)[vertexPtrToIndexMap[newVertex._v1]] * newVertex._f1;
                        if (newVertex._v2) norm += (*normals)[vertexPtrToIndexMap[newVertex._v2]] * newVertex._f2;
                        if (newVertex._v3) norm += (*normals)[vertexPtrToIndexMap[newVertex._v3]] * newVertex._f3;
                        if (newVertex._v4) norm += (*normals)[vertexPtrToIndexMap[newVertex._v4]] * newVertex._f4;
                        norm.normalize();
                        normals->push_back(norm);
                    }

                    if (!arrays.empty())
                    {
                        InsertNewVertices inv(newVertex._f1,vertexPtrToIndexMap[newVertex._v1],
                                              newVertex._f2,vertexPtrToIndexMap[newVertex._v2],
                                              newVertex._f3,vertexPtrToIndexMap[newVertex._v3],
                                              newVertex._f4,vertexPtrToIndexMap[newVertex._v4]);

                                                  // assign the rest of the attributes.
                        for(ArrayList::iterator aItr=arrays.begin();
                            aItr!=arrays.end();
                            ++aItr)
                        {
                            (*aItr)->accept(inv);
                        }
                    }
                }

            }

            for(PrimList::iterator primItr=_primList.begin();
                primItr!=_primList.end();
                ++primItr)
            {
                Prim* prim = primItr->get();

                osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(prim->_mode);
                for(Prim::VecList::iterator vitr=prim->_vertices.begin();
                    vitr!=prim->_vertices.end();
                    ++vitr)
                {
                    elements->push_back(vertexPtrToIndexMap[*vitr]);
                }

                if (primItr==_primList.begin())
                {
                    // first new primitive so overwrite the previous polygon.
                    geom.getPrimitiveList()[primNo] = elements;
                }
                else
                {
                    // subsequence primtives add to the back of the primitive list.
                    geom.addPrimitive(elements);
                }
            }

        }

    }
}

void Tesselator::begin(GLenum mode)
{
    _primList.push_back(new Prim(mode));
}

void Tesselator::vertex(osg::Vec3* vertex)
{
    if (!_primList.empty())
    {
        Prim* prim = _primList.back().get();
        prim->_vertices.push_back(vertex);

    }
}

void Tesselator::combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4])
{
    _newVertexList[vertex]=NewVertex(weight[0],(Vec3*)vertex_data[0],
                                     weight[1],(Vec3*)vertex_data[1],
                                     weight[2],(Vec3*)vertex_data[2],
                                     weight[3],(Vec3*)vertex_data[3]);
}

void Tesselator::end()
{
    // no need to do anything right now...
}

void Tesselator::error(GLenum errorCode)
{
    _errorCode = errorCode;
}

void CALLBACK Tesselator::beginCallback(GLenum which, void* userData)
{
    ((Tesselator*)userData)->begin(which);
}

void CALLBACK Tesselator::endCallback(void* userData)
{
    ((Tesselator*)userData)->end();
}

void CALLBACK Tesselator::vertexCallback(GLvoid *data, void* userData)
{
    ((Tesselator*)userData)->vertex((Vec3*)data);
}

void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* vertex_data[4],
                              GLfloat weight[4], void** outData,
                              void* /*userData*/)
{
    Vec3* newData = new osg::Vec3(coords[0],coords[1],coords[2]);
    *outData = newData;
    //((Tesselator*)userData)->combine(newData);
    s_currentTesselator->combine(newData,vertex_data,weight);
}

void CALLBACK Tesselator::errorCallback(GLenum errorCode, void* userData)
{
    ((Tesselator*)userData)->error(errorCode);
}
<commit_msg>Rewrote the apply_imp template method so that it takes an initialization paramater.<commit_after>#include <osg/GL>
#include <osg/GLU>

#include <osg/Notify>
#include <osgUtil/Tesselator>

using namespace osg;
using namespace osgUtil;

static Tesselator* s_currentTesselator=0;

Tesselator::Tesselator()
{
    _tobj = 0;
    _errorCode = 0;
}

Tesselator::~Tesselator()
{
    if (_tobj) gluDeleteTess(_tobj);
}

void Tesselator::beginTesselation()
{
    reset();

    if (!_tobj) _tobj = gluNewTess();

    gluTessCallback(_tobj, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK*)()) vertexCallback);
    gluTessCallback(_tobj, GLU_TESS_BEGIN_DATA,  (GLvoid (CALLBACK*)()) beginCallback);
    gluTessCallback(_tobj, GLU_TESS_END_DATA,    (GLvoid (CALLBACK*)()) endCallback);
    gluTessCallback(_tobj, GLU_TESS_COMBINE,     (GLvoid (CALLBACK*)()) combineCallback);
    gluTessCallback(_tobj, GLU_TESS_ERROR_DATA,  (GLvoid (CALLBACK*)()) errorCallback);

    gluTessBeginPolygon(_tobj,this);

    s_currentTesselator = this;

}

void Tesselator::beginContour()
{
    if (_tobj)
    {
        gluTessBeginContour(_tobj);
    }
}

void Tesselator::addVertex(osg::Vec3* vertex)
{
    if (_tobj)
    {
        Vec3d* data = new Vec3d;
        _coordData.push_back(data);
        (*data)._v[0]=(*vertex)[0];
        (*data)._v[1]=(*vertex)[1];
        (*data)._v[2]=(*vertex)[2];
        gluTessVertex(_tobj,data->_v,vertex);
    }
}

void Tesselator::endContour()
{
    if (_tobj)
    {
        gluTessEndContour(_tobj);
    }
}

void Tesselator::endTesselation()
{
    if (_tobj)
    {
        gluTessEndPolygon(_tobj);
        gluDeleteTess(_tobj);
        _tobj = 0;

        if (_errorCode!=0)
        {
           const GLubyte *estring = gluErrorString((GLenum)_errorCode);
           osg::notify(osg::WARN)<<"Tessellation Error: "<<estring<< std::endl;
        }
    }
}

void Tesselator::reset()
{
    if (_tobj)
    {
        gluDeleteTess(_tobj);
        _tobj = 0;
    }
    _primList.clear();
    _coordData.clear();
    _newVertexList.clear();
    _errorCode = 0;
}

class InsertNewVertices : public osg::ArrayVisitor
{
    public:

        float _f1,_f2,_f3,_f4;
        unsigned int _i1,_i2,_i3,_i4;

        InsertNewVertices(float f1,unsigned int i1,
                          float f2,unsigned int i2,
                          float f3,unsigned int i3,
                          float f4,unsigned int i4):
                            _f1(f1),_f2(f2),_f3(f3),_f4(f4),
                            _i1(i1),_i2(i2),_i3(i3),_i4(i4){}

        template <class ARRAY,class TYPE>
        void apply_imp(ARRAY& array,TYPE initialValue)
        {
            TYPE val = initialValue;
            if (_f1) val += static_cast<TYPE>(array[_i1] * _f1);
            if (_f2) val += static_cast<TYPE>(array[_i2] * _f2);
            if (_f3) val += static_cast<TYPE>(array[_i3] * _f3);
            if (_f4) val += static_cast<TYPE>(array[_i4] * _f4);

            array.push_back(val);
        }

        virtual void apply(osg::ByteArray& ba) { apply_imp(ba,GLbyte(0)); }
        virtual void apply(osg::ShortArray& ba) { apply_imp(ba,GLshort(0)); }
        virtual void apply(osg::IntArray& ba) { apply_imp(ba,GLint(0)); }
        virtual void apply(osg::UByteArray& ba) { apply_imp(ba,GLubyte(0)); }
        virtual void apply(osg::UShortArray& ba) { apply_imp(ba,GLushort(0)); }
        virtual void apply(osg::UIntArray& ba) { apply_imp(ba,GLuint(0)); }
        virtual void apply(osg::UByte4Array& ba) { apply_imp(ba,UByte4()); }
        virtual void apply(osg::FloatArray& ba) { apply_imp(ba,float(0)); }
        virtual void apply(osg::Vec2Array& ba) { apply_imp(ba,Vec2()); }
        virtual void apply(osg::Vec3Array& ba) { apply_imp(ba,Vec3()); }
        virtual void apply(osg::Vec4Array& ba) { apply_imp(ba,Vec4()); }

};

void Tesselator::retesselatePolygons(osg::Geometry& geom)
{
    Vec3Array* vertices = geom.getVertexArray();
    if (!vertices || vertices->empty() || geom.getPrimitiveList().empty()) return;

    int noPrimitiveAtStart = geom.getPrimitiveList().size();
    for(int primNo=0;primNo<noPrimitiveAtStart;++primNo)
    {
        osg::Primitive* primitive = geom.getPrimitiveList()[primNo].get();
        if (primitive->getMode()==osg::Primitive::POLYGON)
        {
            beginTesselation();
            beginContour();

            switch(primitive->getType())
            {
                case(osg::Primitive::DrawArraysPrimitiveType):
                {
                    osg::DrawArrays* drawArray = static_cast<osg::DrawArrays*>(primitive);
                    unsigned int first = drawArray->getFirst();
                    unsigned int last = first+drawArray->getCount();
                    for(unsigned int i=first;i<last;++i)
                    {
                        addVertex(&((*vertices)[i]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUBytePrimitiveType):
                {
                    osg::DrawElementsUByte* drawElements = static_cast<osg::DrawElementsUByte*>(primitive);
                    for(osg::DrawElementsUByte::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUShortPrimitiveType):
                {
                    osg::DrawElementsUShort* drawElements = static_cast<osg::DrawElementsUShort*>(primitive);
                    for(osg::DrawElementsUShort::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                case(osg::Primitive::DrawElementsUIntPrimitiveType):
                {
                    osg::DrawElementsUInt* drawElements = static_cast<osg::DrawElementsUInt*>(primitive);
                    for(osg::DrawElementsUInt::iterator indexItr=drawElements->begin();
                        indexItr!=drawElements->end();
                        ++indexItr)
                    {
                        addVertex(&((*vertices)[*indexItr]));
                    }
                    break;
                }
                default:
                    break;
            }

            endContour();
            endTesselation();

            typedef std::map<osg::Vec3*,unsigned int> VertexPtrToIndexMap;
            VertexPtrToIndexMap vertexPtrToIndexMap;

            // populate the VertexPtrToIndexMap.
            for(unsigned int vi=0;vi<vertices->size();++vi)
            {
                vertexPtrToIndexMap[&((*vertices)[vi])] = vi;
            }

            if (!_newVertexList.empty())
            {

                osg::Vec3Array* normals = NULL;
                if (geom.getNormalBinding()==osg::Geometry::BIND_PER_VERTEX)
                {
                    normals = geom.getNormalArray();
                }

                typedef std::vector<osg::Array*> ArrayList;
                ArrayList arrays;

                if (geom.getColorBinding()==osg::Geometry::BIND_PER_VERTEX)
                {
                    arrays.push_back(geom.getColorArray());
                }

                osg::Geometry::TexCoordArrayList& tcal = geom.getTexCoordArrayList();
                for(osg::Geometry::TexCoordArrayList::iterator tcalItr=tcal.begin();
                    tcalItr!=tcal.end();
                    ++tcalItr)
                {
                    if (tcalItr->valid())
                    {
                        arrays.push_back(tcalItr->get());
                    }
                }

                // now add any new vertices that are required.
                for(NewVertexList::iterator itr=_newVertexList.begin();
                    itr!=_newVertexList.end();
                    ++itr)
                {
                    osg::Vec3* vertex = itr->first;
                    NewVertex& newVertex = itr->second;

                    // assign vertex.
                    vertexPtrToIndexMap[vertex]=vertices->size();
                    vertices->push_back(*vertex);

                    // assign normals
                    if (normals)
                    {
                        osg::Vec3 norm(0.0f,0.0f,0.0f);
                        if (newVertex._v1) norm += (*normals)[vertexPtrToIndexMap[newVertex._v1]] * newVertex._f1;
                        if (newVertex._v2) norm += (*normals)[vertexPtrToIndexMap[newVertex._v2]] * newVertex._f2;
                        if (newVertex._v3) norm += (*normals)[vertexPtrToIndexMap[newVertex._v3]] * newVertex._f3;
                        if (newVertex._v4) norm += (*normals)[vertexPtrToIndexMap[newVertex._v4]] * newVertex._f4;
                        norm.normalize();
                        normals->push_back(norm);
                    }

                    if (!arrays.empty())
                    {
                        InsertNewVertices inv(newVertex._f1,vertexPtrToIndexMap[newVertex._v1],
                                              newVertex._f2,vertexPtrToIndexMap[newVertex._v2],
                                              newVertex._f3,vertexPtrToIndexMap[newVertex._v3],
                                              newVertex._f4,vertexPtrToIndexMap[newVertex._v4]);

                                                  // assign the rest of the attributes.
                        for(ArrayList::iterator aItr=arrays.begin();
                            aItr!=arrays.end();
                            ++aItr)
                        {
                            (*aItr)->accept(inv);
                        }
                    }
                }

            }

            for(PrimList::iterator primItr=_primList.begin();
                primItr!=_primList.end();
                ++primItr)
            {
                Prim* prim = primItr->get();

                osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(prim->_mode);
                for(Prim::VecList::iterator vitr=prim->_vertices.begin();
                    vitr!=prim->_vertices.end();
                    ++vitr)
                {
                    elements->push_back(vertexPtrToIndexMap[*vitr]);
                }

                if (primItr==_primList.begin())
                {
                    // first new primitive so overwrite the previous polygon.
                    geom.getPrimitiveList()[primNo] = elements;
                }
                else
                {
                    // subsequence primtives add to the back of the primitive list.
                    geom.addPrimitive(elements);
                }
            }

        }

    }
}

void Tesselator::begin(GLenum mode)
{
    _primList.push_back(new Prim(mode));
}

void Tesselator::vertex(osg::Vec3* vertex)
{
    if (!_primList.empty())
    {
        Prim* prim = _primList.back().get();
        prim->_vertices.push_back(vertex);

    }
}

void Tesselator::combine(osg::Vec3* vertex,void* vertex_data[4],GLfloat weight[4])
{
    _newVertexList[vertex]=NewVertex(weight[0],(Vec3*)vertex_data[0],
                                     weight[1],(Vec3*)vertex_data[1],
                                     weight[2],(Vec3*)vertex_data[2],
                                     weight[3],(Vec3*)vertex_data[3]);
}

void Tesselator::end()
{
    // no need to do anything right now...
}

void Tesselator::error(GLenum errorCode)
{
    _errorCode = errorCode;
}

void CALLBACK Tesselator::beginCallback(GLenum which, void* userData)
{
    ((Tesselator*)userData)->begin(which);
}

void CALLBACK Tesselator::endCallback(void* userData)
{
    ((Tesselator*)userData)->end();
}

void CALLBACK Tesselator::vertexCallback(GLvoid *data, void* userData)
{
    ((Tesselator*)userData)->vertex((Vec3*)data);
}

void CALLBACK Tesselator::combineCallback(GLdouble coords[3], void* vertex_data[4],
                              GLfloat weight[4], void** outData,
                              void* /*userData*/)
{
    Vec3* newData = new osg::Vec3(coords[0],coords[1],coords[2]);
    *outData = newData;
    //((Tesselator*)userData)->combine(newData);
    s_currentTesselator->combine(newData,vertex_data,weight);
}

void CALLBACK Tesselator::errorCallback(GLenum errorCode, void* userData)
{
    ((Tesselator*)userData)->error(errorCode);
}
<|endoftext|>