Exemplo n.º 1
0
void GLFWCALL PhysicsThreadFun( void *arg )
{
    while( running )
    {
        // Lock mutex
        glfwLockMutex( thread_sync.particles_lock );

        // Wait for particle drawing to be done
        while( running && thread_sync.p_frame > thread_sync.d_frame )
        {
            glfwWaitCond( thread_sync.d_done, thread_sync.particles_lock,
                          0.1 );
        }

        // No longer running?
        if( !running )
        {
            break;
        }

        // Update particles
        ParticleEngine( thread_sync.t, thread_sync.dt );

        // Update frame counter
        thread_sync.p_frame ++;

        // Unlock mutex and signal drawing thread
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.p_done );
    }
}
/* Audio_Manager::run: main loop */
void Audio_Manager::run()
{
   int i;
   Audio_Link *link;
   char *buff, *save;
   char *alias, *file;

   /* create initial threads */
   for(i = 0; i < AUDIOMANAGER_INITIALNTHREAD; i++) {
      link = new Audio_Link;
      link->audio_thread.setupAndStart(m_mmdagent);
      link->next = m_list;
      m_list = link;
   }

   while(m_kill == false) {
      /* wait playing event */
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      Audio_EventQueue_dequeue(&m_bufferQueue, &buff);
      m_count--;
      glfwUnlockMutex(m_mutex);

      if(buff != NULL) {
         alias = MMDAgent_strtok(buff, "|", &save);
         file = MMDAgent_strtok(NULL, "|", &save);

         if(alias != NULL && file != NULL) {
            /* check alias */
            for(i = 0, link = m_list; link; link = link->next, i++)
               if(link->audio_thread.checkAlias(alias))
                  break;
            if(link) {
               link->audio_thread.stop(); /* if the same alias is playing, stop immediately */
            } else {
               for(i = 0, link = m_list; link; link = link->next, i++)
                  if(link->audio_thread.isRunning() && link->audio_thread.isPlaying() == false)
                     break;
               if(link == NULL) {
                  link = new Audio_Link;
                  link->audio_thread.setupAndStart(m_mmdagent);
                  link->next = m_list;
                  m_list = link;
               }
            }
            /* set */
            link->audio_thread.play(alias, file);
         }
         free(buff); /* free buffer */
      }
   }
}
Exemplo n.º 3
0
/* Audio_Thread::run: main thread loop for audio */
void Audio_Thread::run()
{
   Audio audio;
   char *alias, *file;
   bool lipsync;

   while (m_kill == false) {
      /* wait event */
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      alias = MMDAgent_strdup(m_alias);
      file = MMDAgent_strdup(m_file);
      m_count--;
      glfwUnlockMutex(m_mutex);

      m_playing = true;

      /* open and start audio */
      Audio_initialize(&audio);
      if(Audio_openAndStart(&audio, alias, file) == true) {

         lipsync = startLipsync(file);

         /* send SOUND_EVENT_START */
         m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTART, "%s", alias);

         /* wait to stop audio */
         Audio_waitToStop(&audio, alias, &m_playing);

         if(lipsync) stopLipsync();

         /* send SOUND_EVENT_STOP */
         m_mmdagent->sendMessage(AUDIOTHREAD_EVENTSTOP, "%s", alias);

         /* close audio file */
         Audio_close(&audio, alias);
      }

      if(alias) free(alias);
      if(file) free(file);
      Audio_clear(&audio);
      m_playing = false;
   }
}
Exemplo n.º 4
0
/* Open_JTalk_Manager::run: main loop */
void Open_JTalk_Manager::run()
{
   int i;
   Open_JTalk_Link *link;
   char *buff, *save;
   char *chara, *style, *text;
   bool ret = true;

   /* create initial threads */
   for(i = 0; i < OPENJTALKMANAGER_INITIALNTHREAD; i++) {
      link = new Open_JTalk_Link;
      if(link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config) == false)
         ret = false;
      link->next = m_list;
      m_list = link;
   }

   if(ret == false)
      return;

   while(m_kill == false) {
      glfwLockMutex(m_mutex);
      while(m_count <= 0) {
         glfwWaitCond(m_cond, m_mutex, GLFW_INFINITY);
         if(m_kill == true)
            return;
      }
      Open_JTalk_EventQueue_dequeue(&m_bufferQueue, &buff);
      m_count--;
      glfwUnlockMutex(m_mutex);

      if(buff != NULL) {
         chara = MMDAgent_strtok(buff, "|", &save);
         style = MMDAgent_strtok(NULL, "|", &save);
         text = MMDAgent_strtok(NULL, "|", &save);

         if(chara != NULL && style != NULL && text != NULL) {
            /* check character */
            for(i = 0, link = m_list; link; link = link->next, i++)
               if(link->open_jtalk_thread.checkCharacter(chara) == true)
                  break;
            if(link) {
               if(link->open_jtalk_thread.isSpeaking() == true)
                  link->open_jtalk_thread.stop(); /* if the same character is speaking, stop immediately */
            } else {
               for(i = 0, link = m_list; link; link = link->next, i++)
                  if(link->open_jtalk_thread.isRunning() == true && link->open_jtalk_thread.isSpeaking() == false)
                     break;
               if(link == NULL) {
                  link = new Open_JTalk_Link;
                  link->open_jtalk_thread.loadAndStart(m_mmdagent, m_dicDir, m_config);
                  link->next = m_list;
                  m_list = link;
               }
            }
            /* set */
            link->open_jtalk_thread.synthesis(chara, style, text);
         }
         free(buff); /* free buffer */
      }
   }
}
Exemplo n.º 5
0
void DrawParticles( double t, float dt )
{
    int       i, particle_count;
    VERTEX    vertex_array[ BATCH_PARTICLES * PARTICLE_VERTS ], *vptr;
    float     alpha;
    GLuint    rgba;
    VEC       quad_lower_left, quad_lower_right;
    GLfloat   mat[ 16 ];
    PARTICLE  *pptr;

    // Here comes the real trick with flat single primitive objects (s.c.
    // "billboards"): We must rotate the textured primitive so that it
    // always faces the viewer (is coplanar with the view-plane).
    // We:
    //   1) Create the primitive around origo (0,0,0)
    //   2) Rotate it so that it is coplanar with the view plane
    //   3) Translate it according to the particle position
    // Note that 1) and 2) is the same for all particles (done only once).

    // Get modelview matrix. We will only use the upper left 3x3 part of
    // the matrix, which represents the rotation.
    glGetFloatv( GL_MODELVIEW_MATRIX, mat );

    // 1) & 2) We do it in one swift step:
    // Although not obvious, the following six lines represent two matrix/
    // vector multiplications. The matrix is the inverse 3x3 rotation
    // matrix (i.e. the transpose of the same matrix), and the two vectors
    // represent the lower left corner of the quad, PARTICLE_SIZE/2 *
    // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0).
    // The upper left/right corners of the quad is always the negative of
    // the opposite corners (regardless of rotation).
    quad_lower_left.x = (-PARTICLE_SIZE/2) * (mat[0] + mat[1]);
    quad_lower_left.y = (-PARTICLE_SIZE/2) * (mat[4] + mat[5]);
    quad_lower_left.z = (-PARTICLE_SIZE/2) * (mat[8] + mat[9]);
    quad_lower_right.x = (PARTICLE_SIZE/2) * (mat[0] - mat[1]);
    quad_lower_right.y = (PARTICLE_SIZE/2) * (mat[4] - mat[5]);
    quad_lower_right.z = (PARTICLE_SIZE/2) * (mat[8] - mat[9]);

    // Don't update z-buffer, since all particles are transparent!
    glDepthMask( GL_FALSE );

    // Enable blending
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE );

    // Select particle texture
    if( !wireframe )
    {
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, particle_tex_id );
    }

    // Set up vertex arrays. We use interleaved arrays, which is easier to
    // handle (in most situations) and it gives a linear memeory access
    // access pattern (which may give better performance in some
    // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords,
    // 4 ubytes for color and 3 floats for vertex coord (in that order).
    // Most OpenGL cards / drivers are optimized for this format.
    glInterleavedArrays( GL_T2F_C4UB_V3F, 0, vertex_array );

    // Is particle physics carried out in a separate thread?
    if( multithreading )
    {
        // Wait for particle physics thread to be done
        glfwLockMutex( thread_sync.particles_lock );
        while( running && thread_sync.p_frame <= thread_sync.d_frame )
        {
            glfwWaitCond( thread_sync.p_done, thread_sync.particles_lock,
                          0.1 );
        }

        // Store the frame time and delta time for the physics thread
        thread_sync.t  = t;
        thread_sync.dt = dt;

        // Update frame counter
        thread_sync.d_frame ++;
    }
    else
    {
        // Perform particle physics in this thread
        ParticleEngine( t, dt );
    }

    // Loop through all particles and build vertex arrays.
    particle_count = 0;
    vptr = vertex_array;
    pptr = particles;
    for( i = 0; i < MAX_PARTICLES; i ++ )
    {
        if( pptr->active )
        {
            // Calculate particle intensity (we set it to max during 75%
            // of its life, then it fades out)
            alpha =  4.0f * pptr->life;
            if( alpha > 1.0f )
            {
                alpha = 1.0f;
            }

            // Convert color from float to 8-bit (store it in a 32-bit
            // integer using endian independent type casting)
            ((GLubyte *)&rgba)[0] = (GLubyte)(pptr->r * 255.0f);
            ((GLubyte *)&rgba)[1] = (GLubyte)(pptr->g * 255.0f);
            ((GLubyte *)&rgba)[2] = (GLubyte)(pptr->b * 255.0f);
            ((GLubyte *)&rgba)[3] = (GLubyte)(alpha * 255.0f);

            // 3) Translate the quad to the correct position in modelview
            // space and store its parameters in vertex arrays (we also
            // store texture coord and color information for each vertex).

            // Lower left corner
            vptr->s    = 0.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_left.x;
            vptr->y    = pptr->y + quad_lower_left.y;
            vptr->z    = pptr->z + quad_lower_left.z;
            vptr ++;

            // Lower right corner
            vptr->s    = 1.0f;
            vptr->t    = 0.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x + quad_lower_right.x;
            vptr->y    = pptr->y + quad_lower_right.y;
            vptr->z    = pptr->z + quad_lower_right.z;
            vptr ++;

            // Upper right corner
            vptr->s    = 1.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_left.x;
            vptr->y    = pptr->y - quad_lower_left.y;
            vptr->z    = pptr->z - quad_lower_left.z;
            vptr ++;

            // Upper left corner
            vptr->s    = 0.0f;
            vptr->t    = 1.0f;
            vptr->rgba = rgba;
            vptr->x    = pptr->x - quad_lower_right.x;
            vptr->y    = pptr->y - quad_lower_right.y;
            vptr->z    = pptr->z - quad_lower_right.z;
            vptr ++;

            // Increase count of drawable particles
            particle_count ++;
        }

        // If we have filled up one batch of particles, draw it as a set
        // of quads using glDrawArrays.
        if( particle_count >= BATCH_PARTICLES )
        {
            // The first argument tells which primitive type we use (QUAD)
            // The second argument tells the index of the first vertex (0)
            // The last argument is the vertex count
            glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );
            particle_count = 0;
            vptr = vertex_array;
        }

        // Next particle
        pptr ++;
    }

    // We are done with the particle data: Unlock mutex and signal physics
    // thread
    if( multithreading )
    {
        glfwUnlockMutex( thread_sync.particles_lock );
        glfwSignalCond( thread_sync.d_done );
    }

    // Draw final batch of particles (if any)
    glDrawArrays( GL_QUADS, 0, PARTICLE_VERTS * particle_count );

    // Disable vertex arrays (Note: glInterleavedArrays implicitly called
    // glEnableClientState for vertex, texture coord and color arrays)
    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_TEXTURE_COORD_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );

    // Disable texturing and blending
    glDisable( GL_TEXTURE_2D );
    glDisable( GL_BLEND );

    // Allow Z-buffer updates again
    glDepthMask( GL_TRUE );
}