// // Interface//// Allows you to connect to and see/hear the shared 3D space.// Optionally uses serialUSB connection to get gyro data for head movement.// Optionally gets UDP stream from transmitter to animate controller/hand.// // Usage: The interface client first attempts to contact a domain server to// discover the appropriate audio, voxel, and avatar servers to contact.// Right now, the default domain server is "highfidelity.below92.com"// You can change the domain server to use your own by editing the// DOMAIN_HOSTNAME or DOMAIN_IP strings in the file AgentList.cpp////// Welcome Aboard!////// Keyboard Commands: //// / = toggle stats display// spacebar = reset gyros/head position// h = render Head facing yourself (mirror)// l = show incoming gyro levels// #include "InterfaceConfig.h"#include <iostream>#include <fstream>#include <math.h>#include <string.h>#include <sstream>#include <stdio.h>#include <stdlib.h> #ifdef _WIN32#include "Syssocket.h"#include "Systime.h"#else#include <sys/time.h>#include <arpa/inet.h>#include <ifaddrs.h>#endif #include <pthread.h> #include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/type_ptr.hpp> #include "Field.h"#include "world.h"#include "Util.h"#ifndef _WIN32#include "Audio.h"#endif #include "FieldOfView.h"#include "Stars.h" #include "MenuRow.h"#include "MenuColumn.h"#include "Menu.h"#include "Head.h"#include "Hand.h"#include "Camera.h"#include "Particle.h"#include "Texture.h"#include "Cloud.h"#include <AgentList.h>#include <AgentTypes.h>#include "VoxelSystem.h"#include "Lattice.h"#include "Finger.h"#include "Oscilloscope.h"#include "UDPSocket.h"#include "SerialInterface.h"#include <PerfStat.h>#include <SharedUtil.h>#include <PacketHeaders.h> using namespace std; AgentList agentList(AGENT_TYPE_INTERFACE);pthread_t networkReceiveThread;bool stopNetworkReceiveThread = false; int packetCount = 0;int packetsPerSecond = 0; int bytesPerSecond = 0;int bytesCount = 0; int headMirror = 1; // Whether to mirror own head when viewing it int WIDTH = 1200; // Window sizeint HEIGHT = 800;int fullscreen = 0; bool wantColorRandomizer = true; // for addSphere and load file Oscilloscope audioScope(256,200,true); Head myHead; // The rendered head of oneselfCamera myCamera; // My view onto the world (sometimes on myself :) // Starfield informationchar starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";FieldOfView fov;Stars stars;#ifdef STARFIELD_KEYSint starsTiles = 20;double starsLod = 1.0;#endif bool showingVoxels = false; glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE); ParticleSystem balls(0, box, false, // Wrap? 0.02f, // Noise 0.3f, // Size scale 0.0 // Gravity ); Cloud cloud(0, // Particles box, // Bounding Box false // Wrap ); VoxelSystem voxels; Lattice lattice(160,100);Finger myFinger(WIDTH, HEIGHT);Field field; #ifndef _WIN32Audio audio(&audioScope, &myHead);#endif #define IDLE_SIMULATE_MSECS 8 // How often should call simulate and other stuff // in the idle loop? float yaw = 0.f; // The yaw, pitch for the avatar headfloat pitch = 0.f; float startYaw = 122.f;float renderPitch = 0.f;float renderYawRate = 0.f;float renderPitchRate = 0.f; // Where one's own agent begins in the world (needs to become a dynamic thing passed to the program)glm::vec3 start_location(6.1f, 0, 1.4f); int statsOn = 0; // Whether to show onscreen text overlay with statsbool starsOn = false; // Whether to display the starsbool paintOn = false; // Whether to paint voxels as you fly aroundVoxelDetail paintingVoxel; // The voxel we're painting if we're paintingunsigned char dominantColor = 0; // The dominant color of the voxel we're paintingbool perfStatsOn = false; // Do we want to display perfStats?int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels int displayLevels = 0;int displayHead = 0;int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movementint headMouseX, headMouseY; int mouseX, mouseY; // Where is the mouseint mouseStartX, mouseStartY; // Mouse location at start of last down clickint mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menuint menuOn = 0; // Whether to show onscreen menu //// Serial USB Variables// SerialInterface serialPort;int latency_display = 1; glm::vec3 gravity;int first_measurement = 1;//int samplecount = 0; // Frame rate Measurement int frameCount = 0; float FPS = 120.f;timeval timerStart, timerEnd;timeval lastTimeIdle;double elapsedTime; // Particles float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.0f }; // larger Z = smaller particlesfloat pointer_attenuation_quadratic[] = { 1.0f, 0.0f, 0.0f }; // for 2D view #ifdef MARKER_CAPTURE /*** Marker Capture ***/ #define MARKER_CAPTURE_INTERVAL 1 MarkerCapture marker_capturer(CV_CAP_ANY); // Create a new marker capturer, attached to any valid camera. MarkerAcquisitionView marker_acq_view(&marker_capturer); bool marker_capture_enabled = true; bool marker_capture_display = true; IplImage* marker_capture_frame; IplImage* marker_capture_blob_frame; pthread_mutex_t frame_lock; #endif // Every second, check the frame rates and other stuffvoid Timer(int extra){ gettimeofday(&timerEnd, NULL); FPS = (float)frameCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); packetsPerSecond = (float)packetCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); bytesPerSecond = (float)bytesCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); frameCount = 0; packetCount = 0; bytesCount = 0; glutTimerFunc(1000,Timer,0); gettimeofday(&timerStart, NULL); // Ping the agents we can see agentList.pingAgents(); // if we haven't detected gyros, check for them now if (!serialPort.active) { serialPort.pair(); }} void displayStats(void){ int statsVerticalOffset = 50; if (menuOn == 0) { statsVerticalOffset = 8; } // bitmap chars are about 10 pels high char legend[] = "/ - toggle this display, Q - exit, H - show head, M - show hand, T - test audio"; drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, legend); char legend2[] = "* - toggle stars, & - toggle paint mode, '-' - send erase all, '%' - send add scene"; drawtext(10, statsVerticalOffset + 32, 0.10f, 0, 1.0, 0, legend2); glm::vec3 headPos = myHead.getPos(); char stats[200]; sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)=( %f , %f , %f )", FPS, packetsPerSecond, bytesPerSecond, headPos.x,headPos.y,headPos.z); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); if (serialPort.active) { sprintf(stats, "ADC samples = %d, LED = %d", serialPort.getNumSamples(), serialPort.getLED()); drawtext(300, statsVerticalOffset + 30, 0.10f, 0, 1.0, 0, stats); } // Output the ping times to the various agents // std::stringstream pingTimes;// pingTimes << "Agent Pings, msecs:";// for (int i = 0; i < getAgentCount(); i++) {// pingTimes << " " << getAgentAddress(i) << ": " << getAgentPing(i);// }// drawtext(10,50,0.10, 0, 1.0, 0, (char *)pingTimes.str().c_str()); std::stringstream voxelStats; voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered(); drawtext(10, statsVerticalOffset + 70, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() << " (" << voxels.getVoxelsCreatedRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() << " (" << voxels.getVoxelsColoredRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Bytes Read: " << voxels.getVoxelsBytesRead() << " (" << voxels.getVoxelsBytesReadRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); long int voxelsBytesPerColored = voxels.getVoxelsColored() ? voxels.getVoxelsBytesRead()/voxels.getVoxelsColored() : 0; long int voxelsBytesPerColoredAvg = voxels.getVoxelsColoredRunningAverage() ? voxels.getVoxelsBytesReadRunningAverage()/voxels.getVoxelsColoredRunningAverage() : 0; voxelStats << "Voxels Bytes per Colored: " << voxelsBytesPerColored << " (" << voxelsBytesPerColoredAvg << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); if (::perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; int lines = PerfStat::DumpStats(perfStatLinesArray); int atZ = 150; // arbitrary place on screen that looks good for (int line=0; line < lines; line++) { drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); delete perfStatLinesArray[line]; // we're responsible for cleanup perfStatLinesArray[line]=NULL; atZ+=20; // height of a line } delete []perfStatLinesArray; // we're responsible for cleanup }} void initDisplay(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadeModel (GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); if (fullscreen) glutFullScreen();} void init(void){ voxels.init(); voxels.setViewerHead(&myHead); myHead.setRenderYaw(startYaw); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; stars.readInput(starFile, 0); // Initialize Field values field = Field(); if (noiseOn) { myHead.setNoise(noise); } myHead.setPos(start_location ); myCamera.setPosition( start_location ); #ifdef MARKER_CAPTURE if(marker_capture_enabled){ marker_capturer.position_updated(&position_updated); marker_capturer.frame_updated(&marker_frame_available); if(!marker_capturer.init_capture()){ printf("Camera-based marker capture initialized.\n"); }else{ printf("Error initializing camera-based marker capture.\n"); } }#endif gettimeofday(&timerStart, NULL); gettimeofday(&lastTimeIdle, NULL);} void terminate () { // Close serial port //close(serial_fd); #ifndef _WIN32 audio.terminate(); #endif stopNetworkReceiveThread = true; pthread_join(networkReceiveThread, NULL); exit(EXIT_SUCCESS);} void reset_sensors(){ // // Reset serial I/O sensors // myHead.setRenderYaw(startYaw); yaw = renderYawRate = 0; pitch = renderPitch = renderPitchRate = 0; myHead.setPos(start_location); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; myHead.reset(); if (serialPort.active) { serialPort.resetTrailingAverages(); }} void simulateHand(float deltaTime) { // If mouse is being dragged, send current force to the hand controller if (mousePressed == 1) { // Add a velocity to the hand corresponding to the detected size of the drag vector const float MOUSE_HAND_FORCE = 1.5; float dx = mouseX - mouseStartX; float dy = mouseY - mouseStartY; glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); myHead.hand->addVelocity(vel*deltaTime); }} void simulateHead(float frametime)// Using serial data, update avatar/render position and angles{// float measured_pitch_rate = serialPort.getRelativeValue(PITCH_RATE);// float measured_yaw_rate = serialPort.getRelativeValue(YAW_RATE); float measured_pitch_rate = 0; float measured_yaw_rate = 0; //float measured_lateral_accel = serialPort.getRelativeValue(ACCEL_X); //float measured_fwd_accel = serialPort.getRelativeValue(ACCEL_Z); myHead.UpdatePos(frametime, &serialPort, headMirror, &gravity); //------------------------------------------------------------------------------------- // set the position of the avatar //------------------------------------------------------------------------------------- myHead.setAvatarPosition( -myHead.getPos().x, -myHead.getPos().y, -myHead.getPos().z ); // Update head_mouse model const float MIN_MOUSE_RATE = 30.0; const float MOUSE_SENSITIVITY = 0.1f; if (powf(measured_yaw_rate*measured_yaw_rate + measured_pitch_rate*measured_pitch_rate, 0.5) > MIN_MOUSE_RATE) { headMouseX += measured_yaw_rate*MOUSE_SENSITIVITY; headMouseY += measured_pitch_rate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH; } headMouseX = max(headMouseX, 0); headMouseX = min(headMouseX, WIDTH); headMouseY = max(headMouseY, 0); headMouseY = min(headMouseY, HEIGHT); // Update render direction (pitch/yaw) based on measured gyro rates const int MIN_YAW_RATE = 100; const int MIN_PITCH_RATE = 100; const float YAW_SENSITIVITY = 0.02; const float PITCH_SENSITIVITY = 0.05; // Update render pitch and yaw rates based on keyPositions const float KEY_YAW_SENSITIVITY = 2.0; if (myHead.getDriveKeys(ROT_LEFT)) renderYawRate -= KEY_YAW_SENSITIVITY*frametime; if (myHead.getDriveKeys(ROT_RIGHT)) renderYawRate += KEY_YAW_SENSITIVITY*frametime; if (fabs(measured_yaw_rate) > MIN_YAW_RATE) { if (measured_yaw_rate > 0) renderYawRate += (measured_yaw_rate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; else renderYawRate += (measured_yaw_rate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; } if (fabs(measured_pitch_rate) > MIN_PITCH_RATE) { if (measured_pitch_rate > 0) renderPitchRate += (measured_pitch_rate - MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; else renderPitchRate += (measured_pitch_rate + MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; } renderPitch += renderPitchRate; // Decay renderPitch toward zero because we never look constantly up/down renderPitch *= (1.f - 2.0*frametime); // Decay angular rates toward zero renderPitchRate *= (1.f - 5.0*frametime); renderYawRate *= (1.f - 7.0*frametime); // Update own head data myHead.setRenderYaw(myHead.getRenderYaw() + renderYawRate); myHead.setRenderPitch(renderPitch); // Get audio loudness data from audio input device float loudness, averageLoudness; #ifndef _WIN32 audio.getInputLoudness(&loudness, &averageLoudness); myHead.setLoudness(loudness); myHead.setAverageLoudness(averageLoudness); #endif // Send my streaming head data to agents that are nearby and need to see it! const int MAX_BROADCAST_STRING = 200; char broadcast_string[MAX_BROADCAST_STRING]; int broadcast_bytes = myHead.getBroadcastData(broadcast_string); agentList.broadcastToAgents(broadcast_string, broadcast_bytes,AgentList::AGENTS_OF_TYPE_VOXEL_AND_INTERFACE); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) {Lines 1–500 of 1381. Load more
// // Interface // // Allows you to connect to and see/hear the shared 3D space. // Optionally uses serialUSB connection to get gyro data for head movement. // Optionally gets UDP stream from transmitter to animate controller/hand. // // Usage: The interface client first attempts to contact a domain server to // discover the appropriate audio, voxel, and avatar servers to contact. // Right now, the default domain server is "highfidelity.below92.com" // You can change the domain server to use your own by editing the // DOMAIN_HOSTNAME or DOMAIN_IP strings in the file AgentList.cpp // // // Welcome Aboard! // // // Keyboard Commands: // // / = toggle stats display // spacebar = reset gyros/head position // h = render Head facing yourself (mirror) // l = show incoming gyro levels // #include "InterfaceConfig.h" #include <iostream> #include <fstream> #include <math.h> #include <string.h> #include <sstream> #include <stdio.h> #include <stdlib.h> #ifdef _WIN32 #include "Syssocket.h" #include "Systime.h" #else #include <sys/time.h> #include <arpa/inet.h> #include <ifaddrs.h> #endif #include <pthread.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "Field.h" #include "world.h" #include "Util.h" #ifndef _WIN32 #include "Audio.h" #endif #include "FieldOfView.h" #include "Stars.h" #include "MenuRow.h" #include "MenuColumn.h" #include "Menu.h" #include "Head.h" #include "Hand.h" #include "Camera.h" #include "Particle.h" #include "Texture.h" #include "Cloud.h" #include <AgentList.h> #include <AgentTypes.h> #include "VoxelSystem.h" #include "Lattice.h" #include "Finger.h" #include "Oscilloscope.h" #include "UDPSocket.h" #include "SerialInterface.h" #include <PerfStat.h> #include <SharedUtil.h> #include <PacketHeaders.h> using namespace std; AgentList agentList(AGENT_TYPE_INTERFACE); pthread_t networkReceiveThread; bool stopNetworkReceiveThread = false; int packetCount = 0; int packetsPerSecond = 0; int bytesPerSecond = 0; int bytesCount = 0; int headMirror = 1; // Whether to mirror own head when viewing it int WIDTH = 1200; // Window size int HEIGHT = 800; int fullscreen = 0; bool wantColorRandomizer = true; // for addSphere and load file Oscilloscope audioScope(256,200,true); Head myHead; // The rendered head of oneself Camera myCamera; // My view onto the world (sometimes on myself :) // Starfield information char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; FieldOfView fov; Stars stars; #ifdef STARFIELD_KEYS int starsTiles = 20; double starsLod = 1.0; #endif bool showingVoxels = false; glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE); ParticleSystem balls(0, box, false, // Wrap? 0.02f, // Noise 0.3f, // Size scale 0.0 // Gravity ); Cloud cloud(0, // Particles box, // Bounding Box false // Wrap ); VoxelSystem voxels; Lattice lattice(160,100); Finger myFinger(WIDTH, HEIGHT); Field field; #ifndef _WIN32 Audio audio(&audioScope, &myHead); #endif #define IDLE_SIMULATE_MSECS 8 // How often should call simulate and other stuff // in the idle loop? float yaw = 0.f; // The yaw, pitch for the avatar head float pitch = 0.f; float startYaw = 122.f; float renderPitch = 0.f; float renderYawRate = 0.f; float renderPitchRate = 0.f; // Where one's own agent begins in the world (needs to become a dynamic thing passed to the program) glm::vec3 start_location(6.1f, 0, 1.4f); int statsOn = 0; // Whether to show onscreen text overlay with stats bool starsOn = false; // Whether to display the stars bool paintOn = false; // Whether to paint voxels as you fly around VoxelDetail paintingVoxel; // The voxel we're painting if we're painting unsigned char dominantColor = 0; // The dominant color of the voxel we're painting bool perfStatsOn = false; // Do we want to display perfStats? int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels int displayLevels = 0; int displayHead = 0; int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement int headMouseX, headMouseY; int mouseX, mouseY; // Where is the mouse int mouseStartX, mouseStartY; // Mouse location at start of last down click int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu int menuOn = 0; // Whether to show onscreen menu // // Serial USB Variables // SerialInterface serialPort; int latency_display = 1; glm::vec3 gravity; int first_measurement = 1; //int samplecount = 0; // Frame rate Measurement int frameCount = 0; float FPS = 120.f; timeval timerStart, timerEnd; timeval lastTimeIdle; double elapsedTime; // Particles float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.0f }; // larger Z = smaller particles float pointer_attenuation_quadratic[] = { 1.0f, 0.0f, 0.0f }; // for 2D view #ifdef MARKER_CAPTURE /*** Marker Capture ***/ #define MARKER_CAPTURE_INTERVAL 1 MarkerCapture marker_capturer(CV_CAP_ANY); // Create a new marker capturer, attached to any valid camera. MarkerAcquisitionView marker_acq_view(&marker_capturer); bool marker_capture_enabled = true; bool marker_capture_display = true; IplImage* marker_capture_frame; IplImage* marker_capture_blob_frame; pthread_mutex_t frame_lock; #endif // Every second, check the frame rates and other stuff void Timer(int extra) { gettimeofday(&timerEnd, NULL); FPS = (float)frameCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); packetsPerSecond = (float)packetCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); bytesPerSecond = (float)bytesCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); frameCount = 0; packetCount = 0; bytesCount = 0; glutTimerFunc(1000,Timer,0); gettimeofday(&timerStart, NULL); // Ping the agents we can see agentList.pingAgents(); // if we haven't detected gyros, check for them now if (!serialPort.active) { serialPort.pair(); } } void displayStats(void) { int statsVerticalOffset = 50; if (menuOn == 0) { statsVerticalOffset = 8; } // bitmap chars are about 10 pels high char legend[] = "/ - toggle this display, Q - exit, H - show head, M - show hand, T - test audio"; drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, legend); char legend2[] = "* - toggle stars, & - toggle paint mode, '-' - send erase all, '%' - send add scene"; drawtext(10, statsVerticalOffset + 32, 0.10f, 0, 1.0, 0, legend2); glm::vec3 headPos = myHead.getPos(); char stats[200]; sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)=( %f , %f , %f )", FPS, packetsPerSecond, bytesPerSecond, headPos.x,headPos.y,headPos.z); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); if (serialPort.active) { sprintf(stats, "ADC samples = %d, LED = %d", serialPort.getNumSamples(), serialPort.getLED()); drawtext(300, statsVerticalOffset + 30, 0.10f, 0, 1.0, 0, stats); } // Output the ping times to the various agents // std::stringstream pingTimes; // pingTimes << "Agent Pings, msecs:"; // for (int i = 0; i < getAgentCount(); i++) { // pingTimes << " " << getAgentAddress(i) << ": " << getAgentPing(i); // } // drawtext(10,50,0.10, 0, 1.0, 0, (char *)pingTimes.str().c_str()); std::stringstream voxelStats; voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered(); drawtext(10, statsVerticalOffset + 70, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() << " (" << voxels.getVoxelsCreatedRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() << " (" << voxels.getVoxelsColoredRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << "Voxels Bytes Read: " << voxels.getVoxelsBytesRead() << " (" << voxels.getVoxelsBytesReadRunningAverage() << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); long int voxelsBytesPerColored = voxels.getVoxelsColored() ? voxels.getVoxelsBytesRead()/voxels.getVoxelsColored() : 0; long int voxelsBytesPerColoredAvg = voxels.getVoxelsColoredRunningAverage() ? voxels.getVoxelsBytesReadRunningAverage()/voxels.getVoxelsColoredRunningAverage() : 0; voxelStats << "Voxels Bytes per Colored: " << voxelsBytesPerColored << " (" << voxelsBytesPerColoredAvg << "/sec in last "<< COUNTETSTATS_TIME_FRAME << " seconds) "; drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); if (::perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; int lines = PerfStat::DumpStats(perfStatLinesArray); int atZ = 150; // arbitrary place on screen that looks good for (int line=0; line < lines; line++) { drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); delete perfStatLinesArray[line]; // we're responsible for cleanup perfStatLinesArray[line]=NULL; atZ+=20; // height of a line } delete []perfStatLinesArray; // we're responsible for cleanup } } void initDisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadeModel (GL_SMOOTH); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); if (fullscreen) glutFullScreen(); } void init(void) { voxels.init(); voxels.setViewerHead(&myHead); myHead.setRenderYaw(startYaw); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; stars.readInput(starFile, 0); // Initialize Field values field = Field(); if (noiseOn) { myHead.setNoise(noise); } myHead.setPos(start_location ); myCamera.setPosition( start_location ); #ifdef MARKER_CAPTURE if(marker_capture_enabled){ marker_capturer.position_updated(&position_updated); marker_capturer.frame_updated(&marker_frame_available); if(!marker_capturer.init_capture()){ printf("Camera-based marker capture initialized.\n"); }else{ printf("Error initializing camera-based marker capture.\n"); } } #endif gettimeofday(&timerStart, NULL); gettimeofday(&lastTimeIdle, NULL); } void terminate () { // Close serial port //close(serial_fd); #ifndef _WIN32 audio.terminate(); #endif stopNetworkReceiveThread = true; pthread_join(networkReceiveThread, NULL); exit(EXIT_SUCCESS); } void reset_sensors() { // // Reset serial I/O sensors // myHead.setRenderYaw(startYaw); yaw = renderYawRate = 0; pitch = renderPitch = renderPitchRate = 0; myHead.setPos(start_location); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; myHead.reset(); if (serialPort.active) { serialPort.resetTrailingAverages(); } } void simulateHand(float deltaTime) { // If mouse is being dragged, send current force to the hand controller if (mousePressed == 1) { // Add a velocity to the hand corresponding to the detected size of the drag vector const float MOUSE_HAND_FORCE = 1.5; float dx = mouseX - mouseStartX; float dy = mouseY - mouseStartY; glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); myHead.hand->addVelocity(vel*deltaTime); } } void simulateHead(float frametime) // Using serial data, update avatar/render position and angles { // float measured_pitch_rate = serialPort.getRelativeValue(PITCH_RATE); // float measured_yaw_rate = serialPort.getRelativeValue(YAW_RATE); float measured_pitch_rate = 0; float measured_yaw_rate = 0; //float measured_lateral_accel = serialPort.getRelativeValue(ACCEL_X); //float measured_fwd_accel = serialPort.getRelativeValue(ACCEL_Z); myHead.UpdatePos(frametime, &serialPort, headMirror, &gravity); //------------------------------------------------------------------------------------- // set the position of the avatar //------------------------------------------------------------------------------------- myHead.setAvatarPosition( -myHead.getPos().x, -myHead.getPos().y, -myHead.getPos().z ); // Update head_mouse model const float MIN_MOUSE_RATE = 30.0; const float MOUSE_SENSITIVITY = 0.1f; if (powf(measured_yaw_rate*measured_yaw_rate + measured_pitch_rate*measured_pitch_rate, 0.5) > MIN_MOUSE_RATE) { headMouseX += measured_yaw_rate*MOUSE_SENSITIVITY; headMouseY += measured_pitch_rate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH; } headMouseX = max(headMouseX, 0); headMouseX = min(headMouseX, WIDTH); headMouseY = max(headMouseY, 0); headMouseY = min(headMouseY, HEIGHT); // Update render direction (pitch/yaw) based on measured gyro rates const int MIN_YAW_RATE = 100; const int MIN_PITCH_RATE = 100; const float YAW_SENSITIVITY = 0.02; const float PITCH_SENSITIVITY = 0.05; // Update render pitch and yaw rates based on keyPositions const float KEY_YAW_SENSITIVITY = 2.0; if (myHead.getDriveKeys(ROT_LEFT)) renderYawRate -= KEY_YAW_SENSITIVITY*frametime; if (myHead.getDriveKeys(ROT_RIGHT)) renderYawRate += KEY_YAW_SENSITIVITY*frametime; if (fabs(measured_yaw_rate) > MIN_YAW_RATE) { if (measured_yaw_rate > 0) renderYawRate += (measured_yaw_rate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; else renderYawRate += (measured_yaw_rate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; } if (fabs(measured_pitch_rate) > MIN_PITCH_RATE) { if (measured_pitch_rate > 0) renderPitchRate += (measured_pitch_rate - MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; else renderPitchRate += (measured_pitch_rate + MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; } renderPitch += renderPitchRate; // Decay renderPitch toward zero because we never look constantly up/down renderPitch *= (1.f - 2.0*frametime); // Decay angular rates toward zero renderPitchRate *= (1.f - 5.0*frametime); renderYawRate *= (1.f - 7.0*frametime); // Update own head data myHead.setRenderYaw(myHead.getRenderYaw() + renderYawRate); myHead.setRenderPitch(renderPitch); // Get audio loudness data from audio input device float loudness, averageLoudness; #ifndef _WIN32 audio.getInputLoudness(&loudness, &averageLoudness); myHead.setLoudness(loudness); myHead.setAverageLoudness(averageLoudness); #endif // Send my streaming head data to agents that are nearby and need to see it! const int MAX_BROADCAST_STRING = 200; char broadcast_string[MAX_BROADCAST_STRING]; int broadcast_bytes = myHead.getBroadcastData(broadcast_string); agentList.broadcastToAgents(broadcast_string, broadcast_bytes,AgentList::AGENTS_OF_TYPE_VOXEL_AND_INTERFACE); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) {