void OSCTrackSender::sendTracks(Tracker *tracker) { 
	if(! transmitSocket) return; // if no socket skip
	osc::OutboundPacketStream oscStream(buffer, OUTPUT_BUFFER_SIZE);
	oscStream << osc::BeginBundleImmediate;

	oscStream << osc::BeginMessage("/metaInfo");
	oscStream << oscMinX << oscMaxX << oscMinZ << oscMaxZ << worldMinX << worldMaxX << worldMinZ << worldMaxZ << 6; // 6 fields in track data
	oscStream << osc::EndMessage;

	oscStream << osc::BeginMessage("/tracks");
	for(std::vector<Track*>::iterator it = tracker->tracks.begin(); it != tracker->tracks.end(); it++) {
		Track *t = *it;
		float x = (t->x - worldMinX) * scaleX;
		float z = (t->z - worldMinZ) * scaleZ;
		x = (x < oscMinX) ? oscMinX : x;
		z = (z < oscMinZ) ? oscMinZ : z;
		x = (x > oscMaxX) ? oscMaxX : x;
		z = (z > oscMaxZ) ? oscMaxZ : z;
		oscStream << t->id << x << z << (t->age * .001f) << t->provisionality << t->health;
		//std::cout << (*t) << std::endl;

		
	}
	oscStream << osc::EndMessage;

	oscStream << osc::EndBundle;
	transmitSocket->Send(oscStream.Data(), oscStream.Size());

}
void EosTcpClientThread::run()
{
	QString msg = QString("tcp client %1:%2 thread started").arg(m_Ip).arg(m_Port);
	m_PrivateLog.AddInfo( msg.toUtf8().constData() );
	UpdateLog();
	
	const size_t ReconnectDelay = 5000;
	EosTimer reconnectTimer;

	// outer loop for auto-reconnect
	while( m_Run )
	{
		EosTcp *tcp = EosTcp::Create();

		if( tcp->Initialize(m_PrivateLog,m_Ip.toUtf8().constData(),m_Port) )
		{
			OSCParser parser;
			parser.SetRoot(new OSCHandler(*this));
			std::string inPrefix = QString("TCPIN [%1:%2] ").arg(m_Ip).arg(m_Port).toUtf8().constData();
			std::string outPrefix = QString("TCPOUT [%1:%2] ").arg(m_Ip).arg(m_Port).toUtf8().constData();
			
			sPacket packet;

			// connect
			while(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_IN_PROGRESS)
			{
				tcp->Tick(m_PrivateLog);
				UpdateLog();
				msleep(10);
			}

			UpdateLog();

			// send/recv while connected
			if(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_CONNECTED)
			{
				m_Mutex.lock();
				m_NetEventQ.push_back(NET_EVENT_CONNECTED);
				m_Mutex.unlock();
			
				PACKET_Q sendQ;
				OSCStream oscStream(m_FrameMode);
				do
				{
					size_t len = 0;
					const char *data = tcp->Recv(m_PrivateLog, 100, len);
					
					oscStream.Add(data, len);
					
					while( m_Run )
					{
						packet.data = oscStream.GetNextFrame(packet.size);
						if(packet.data && packet.size!=0)
						{
							m_Prefix = inPrefix;
							m_LogMsgType = EosLog::LOG_MSG_TYPE_RECV;
							parser.PrintPacket(*this, packet.data, packet.size);
							parser.ProcessPacket(*this, packet.data, packet.size);
							delete[] packet.data;
						}
						else
							break;
					}

					msleep(1);

					m_Mutex.lock();
					m_SendQ.swap(sendQ);
					m_Mutex.unlock();

					sPacket framedPacket;
					for(PACKET_Q::iterator i=sendQ.begin(); m_Run && i!=sendQ.end(); i++)
					{
						framedPacket.size = i->size;
						framedPacket.data = OSCStream::CreateFrame(m_FrameMode, i->data, framedPacket.size);
						if(framedPacket.data && framedPacket.size!=0)
						{
							if( tcp->Send(m_PrivateLog,framedPacket.data,framedPacket.size) )
							{
								m_Prefix = outPrefix;
								m_LogMsgType = EosLog::LOG_MSG_TYPE_SEND;
								parser.PrintPacket(*this, i->data, i->size);
							}
							delete[] framedPacket.data;
						}
						delete[] i->data;
					}
					sendQ.clear();
				
					UpdateLog();

					msleep(1);
				}
				while(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_CONNECTED);
				
				m_Mutex.lock();
				m_NetEventQ.push_back(NET_EVENT_DISCONNECTED);
				m_Mutex.unlock();
			}
		}

		delete tcp;

		if( m_Run )
		{
			msg = QString("tcp client %1:%2 reconnecting in %3...").arg(m_Ip).arg(m_Port).arg(ReconnectDelay/1000);
			m_PrivateLog.AddInfo( msg.toUtf8().constData() );
			UpdateLog();
		}

		reconnectTimer.Start();
		while(m_Run && !reconnectTimer.GetExpired(ReconnectDelay))
			msleep(10);
	}
	
	msg = QString("tcp client %1:%2 thread ended").arg(m_Ip).arg(m_Port);
	m_PrivateLog.AddInfo( msg.toUtf8().constData() );
	UpdateLog();
}