Bool FileRStream::read(int size, void* d)
{
   Int32 remaining;
   BYTE *p;

   if (strm_status != STRM_OK)                        // exit on stream error
      return FALSE;

	if (size)                                          // if were reading anything...
   {
      remaining = size; p = (BYTE*)d;

      if (buffHead == -1)                             // if the buffer is empty and
      {                                               // this block we want to read is
         if (size < (STRM_BUFFER_SIZE/2))             // less than half the buffer
            if (!fillCache(getPosition()))            // then fill the buffer
               return (FALSE); 
      }

      if (buffHead != -1)                             // if there is a buffer fulfill
      {                                               // as much of the request as 
         size = a_min(buffTail-buffPos+1, remaining);   // possible from the buffer
         memcpy(p, buffer+(buffPos-buffHead), size);
         remaining-= size;
         buffPos  += size;
         p        += size;   
      }
                                                      // if not all fulfilled from the
      if (remaining)                                  // buffer go to disk 
   	   if (ReadFile(hFile, p, remaining, &lastBytes, NULL))
   	   {
            if ((Int32)lastBytes != remaining)
            {
               strm_status = STRM_EOS;
               return FALSE;
            }
         }
         else
         {
   	      return setStatus();
         }

      if (buffPos > buffTail)  buffHead = -1;
   }
   return TRUE;
}
void BoundCreation::MergeAABBs(const AABB * aabb_a, const AABB * aabb_b, AABB * rtn_aabb)
{
	Eigen::Vector3f a_min(aabb_a->GetCenter() - aabb_a->GetExtents());
	Eigen::Vector3f a_max(aabb_a->GetCenter() + aabb_a->GetExtents());
	Eigen::Vector3f b_min(aabb_b->GetCenter() - aabb_b->GetExtents());
	Eigen::Vector3f b_max(aabb_b->GetCenter() + aabb_b->GetExtents());
	Eigen::Vector3f rtn_min;
	Eigen::Vector3f rtn_max;

	rtn_min[0] = std::min(a_min[0], b_min[0]);
	rtn_min[1] = std::min(a_min[1], b_min[1]);
	rtn_min[2] = std::min(a_min[2], b_min[2]);

	rtn_max[0] = std::max(a_max[0], b_max[0]);
	rtn_max[1] = std::max(a_max[1], b_max[1]);
	rtn_max[2] = std::max(a_max[2], b_max[2]);

	rtn_aabb->SetExtents((rtn_max - rtn_min) * 0.5f);
	rtn_aabb->SetCenter((rtn_max + rtn_min) * 0.5f);
}
//---------------------------------------------------------------------------------------
// Processes any remotely received data and call on_cmd_recv() whenever enough data is
// accumulated.
// 
// #Author(s): Conan Reis
void SkUERemote::process_incoming()
  {
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // Connected and data available?
  uint32 bytes_available;

  while (is_connected() && m_socket_p->HasPendingData(bytes_available))
    {
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Get datum size & prep datum
    int32    bytes_read;
    uint32_t datum_size;

    if (m_data_idx == ADef_uint32)
      {
      // Not working on a partially filled datum so get size of new datum
      if (bytes_available < sizeof(uint32_t))
        {
        // wait until there is enough data for size
        return;
        }

      // Read datum size from socket
      m_socket_p->Recv(reinterpret_cast<uint8 *>(&datum_size), sizeof(uint32_t), bytes_read);

      bytes_available -= sizeof(uint32_t);
      datum_size -= ADatum_header_size;
      m_data_in.ensure_size(datum_size, false);
      m_data_in.set_data_length(datum_size);
      m_data_idx = 0u;
      }
    else
      {
      datum_size = m_data_in.get_data_length();
      }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Begin or resume filling datum
    uint32_t cmd;
    uint32_t bytes_to_read;
    uint8 *  buffer_p = m_data_in.get_data_writable();

    while (bytes_available
      || (is_connected() && m_socket_p->HasPendingData(bytes_available)))
      {
      bytes_to_read = a_min(bytes_available, datum_size - m_data_idx);

      // Read datum data from socket
      m_socket_p->Recv(buffer_p + m_data_idx, bytes_to_read, bytes_read);

      m_data_idx += bytes_read;
      bytes_available = 0; // Reset to refresh on next loop

      if (m_data_idx == datum_size)
        {
        // Datum fully received and ready to use
        m_data_idx = ADef_uint32;

        // Parse command from IDE
        A_BYTE_STREAM_IN32(&cmd, &buffer_p);
        on_cmd_recv(eCommand(cmd), buffer_p, datum_size - 4u);

        // Exit filling datum while loop & look for new datum
        break;
        }
      // loop back and continue to try filling datum
      }
    } // While connected and has data
  }