diff --git a/head.cpp b/head.cpp index f2132e788d..98cbf0d0d3 100644 --- a/head.cpp +++ b/head.cpp @@ -62,6 +62,125 @@ void readSensors() } +/* +void update_pos(float frametime) +// Using serial data, update avatar/render position and angles +{ + float measured_pitch_rate = adc_channels[0] - avg_adc_channels[0]; + float measured_yaw_rate = adc_channels[1] - avg_adc_channels[1]; + float measured_lateral_accel = adc_channels[3] - avg_adc_channels[3]; + float measured_fwd_accel = avg_adc_channels[2] - adc_channels[2]; + + // Update avatar head position based on measured gyro rates + const float HEAD_ROTATION_SCALE = 0.20; + const float HEAD_LEAN_SCALE = 0.02; + if (head_mirror) { + myHead.addYaw(measured_yaw_rate * HEAD_ROTATION_SCALE * frametime); + myHead.addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); + myHead.addLean(measured_lateral_accel * frametime * HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); + } else { + myHead.addYaw(measured_yaw_rate * -HEAD_ROTATION_SCALE * frametime); + myHead.addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); + myHead.addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); + } + // Decay avatar head back toward zero + //pitch *= (1.f - 5.0*frametime); + //yaw *= (1.f - 7.0*frametime); + + // Update head_mouse model + const float MIN_MOUSE_RATE = 30.0; + const float MOUSE_SENSITIVITY = 0.1; + if (powf(measured_yaw_rate*measured_yaw_rate + + measured_pitch_rate*measured_pitch_rate, 0.5) > MIN_MOUSE_RATE) + { + head_mouse_x -= measured_yaw_rate*MOUSE_SENSITIVITY; + head_mouse_y += measured_pitch_rate*MOUSE_SENSITIVITY*(float)HEIGHT/(float)WIDTH; + } + head_mouse_x = max(head_mouse_x, 0); + head_mouse_x = min(head_mouse_x, WIDTH); + head_mouse_y = max(head_mouse_y, 0); + head_mouse_y = min(head_mouse_y, HEIGHT); + + // Update render direction (pitch/yaw) based on measured gyro rates + const int MIN_YAW_RATE = 300; + const float YAW_SENSITIVITY = 0.03; + const int MIN_PITCH_RATE = 300; + const float PITCH_SENSITIVITY = 0.04; + + if (fabs(measured_yaw_rate) > MIN_YAW_RATE) + { + if (measured_yaw_rate > 0) + render_yaw_rate -= (measured_yaw_rate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; + else + render_yaw_rate -= (measured_yaw_rate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; + } + if (fabs(measured_pitch_rate) > MIN_PITCH_RATE) + { + if (measured_pitch_rate > 0) + render_pitch_rate += (measured_pitch_rate - MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; + else + render_pitch_rate += (measured_pitch_rate + MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; + } + render_yaw += render_yaw_rate; + render_pitch += render_pitch_rate; + + // Decay render_pitch toward zero because we never look constantly up/down + render_pitch *= (1.f - 2.0*frametime); + + // Decay angular rates toward zero + render_pitch_rate *= (1.f - 5.0*frametime); + render_yaw_rate *= (1.f - 7.0*frametime); + + // Update slide left/right based on accelerometer reading + const int MIN_LATERAL_ACCEL = 20; + const float LATERAL_SENSITIVITY = 0.001; + if (fabs(measured_lateral_accel) > MIN_LATERAL_ACCEL) + { + if (measured_lateral_accel > 0) + lateral_vel += (measured_lateral_accel - MIN_LATERAL_ACCEL) * LATERAL_SENSITIVITY * frametime; + else + lateral_vel += (measured_lateral_accel + MIN_LATERAL_ACCEL) * LATERAL_SENSITIVITY * frametime; + } + + //slide += lateral_vel; + lateral_vel *= (1.f - 4.0*frametime); + + // Update fwd/back based on accelerometer reading + const int MIN_FWD_ACCEL = 20; + const float FWD_SENSITIVITY = 0.001; + + if (fabs(measured_fwd_accel) > MIN_FWD_ACCEL) + { + if (measured_fwd_accel > 0) + fwd_vel += (measured_fwd_accel - MIN_FWD_ACCEL) * FWD_SENSITIVITY * frametime; + else + fwd_vel += (measured_fwd_accel + MIN_FWD_ACCEL) * FWD_SENSITIVITY * frametime; + + } + // Decrease forward velocity + fwd_vel *= (1.f - 4.0*frametime); + + // Update forward vector based on pitch and yaw + fwd_vec[0] = -sinf(render_yaw*PI/180); + fwd_vec[1] = sinf(render_pitch*PI/180); + fwd_vec[2] = cosf(render_yaw*PI/180); + + // Advance location forward + location[0] += fwd_vec[0]*fwd_vel; + location[1] += fwd_vec[1]*fwd_vel; + location[2] += fwd_vec[2]*fwd_vel; + + // Slide location sideways + location[0] += fwd_vec[2]*-lateral_vel; + location[2] += fwd_vec[0]*lateral_vel; + + // Update head and manipulator objects with object with current location + myHead.setPos(glm::vec3(location[0], location[1], location[2])); + balls.updateHand(myHead.getPos() + myHand.getPos(), glm::vec3(0,0,0), myHand.getRadius()); +} +*/ + + void Head::addLean(float x, float z) { // Add Body lean as impulse leanSideways += x; diff --git a/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate b/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate index a232612957..b653b6168a 100644 Binary files a/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate and b/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/main.cpp b/main.cpp index c249238ccd..acb6e3ea94 100644 --- a/main.cpp +++ b/main.cpp @@ -33,7 +33,6 @@ #include #include #include -#include "tga.h" // Texture loader library #include "glm/glm.hpp" #include @@ -60,7 +59,7 @@ int serial_on = 0; // Is serial connection on/off? System wil int audio_on = 0; // Whether to turn on the audio support int simulate_on = 1; -// Network Socket Stuff +// Network Socket Stuff // For testing, add milliseconds of delay for received UDP packets int UDP_socket; int delay = 0; @@ -79,16 +78,9 @@ int target_display = 0; int head_mirror = 0; // Whether to mirror the head when viewing it -unsigned char last_key = 0; - -double ping = 0; - int WIDTH = 1200; int HEIGHT = 800; -#define BOTTOM_MARGIN 0 -#define RIGHT_MARGIN 0 - #define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you Head myHead; // The rendered head of oneself or others Hand myHand(HAND_RADIUS, @@ -108,15 +100,6 @@ Cloud cloud(300000, // Particles false // Wrap ); -// FIELD INFORMATION -// If the simulation 'world' is a box with 10M boundaries, the offset to a field cell is given by: -// element = [x/10 + (y/10)*10 + (z*/10)*100] -// -// The vec(x,y,z) corner of a field cell at element i is: -// -// z = (int)( i / 100) -// y = (int)(i % 100 / 10) -// x = (int)(i % 10) #define RENDER_FRAME_MSECS 10 #define SLEEP 0 @@ -157,7 +140,6 @@ int head_lean_x, head_lean_y; int mouse_x, mouse_y; // Where is the mouse int mouse_pressed = 0; // true if mouse has been pressed (clear when finished) -int accel_x, accel_y; int speed; @@ -257,7 +239,7 @@ void initDisplay(void) void init(void) { - int i, j; + int i; if (audio_on) { Audio::init(); @@ -603,10 +585,7 @@ void display(void) void key(unsigned char k, int x, int y) { // Process keypresses - - last_key = k; - - if (k == 'q') ::terminate(); + if (k == 'q') ::terminate(); if (k == '/') stats_on = !stats_on; // toggle stats if (k == 'n') { @@ -798,7 +777,7 @@ int main(int argc, char** argv) glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); - glutInitWindowSize(RIGHT_MARGIN + WIDTH, BOTTOM_MARGIN + HEIGHT); + glutInitWindowSize(WIDTH, HEIGHT); glutCreateWindow("Interface"); printf( "Created Display Window.\n" ); diff --git a/tga.h b/tga.h deleted file mode 100644 index c45f1730c3..0000000000 --- a/tga.h +++ /dev/null @@ -1,470 +0,0 @@ -#include -#include -#include - -#define IMG_OK 0x1 -#define IMG_ERR_NO_FILE 0x2 -#define IMG_ERR_MEM_FAIL 0x4 -#define IMG_ERR_BAD_FORMAT 0x8 -#define IMG_ERR_UNSUPPORTED 0x40 - -class TGAImg - { - public: - TGAImg(); - ~TGAImg(); - int Load(char* szFilename); - int GetBPP(); - int GetWidth(); - int GetHeight(); - unsigned char* GetImg(); // Return a pointer to image data - unsigned char* GetPalette(); // Return a pointer to VGA palette - - private: - short int iWidth,iHeight,iBPP; - unsigned long lImageSize; - char bEnc; - unsigned char *pImage, *pPalette, *pData; - - // Internal workers - int ReadHeader(); - int LoadRawData(); - int LoadTgaRLEData(); - int LoadTgaPalette(); - void BGRtoRGB(); - void FlipImg(); - }; - - -TGAImg::TGAImg() -{ - pImage=pPalette=pData=NULL; - iWidth=iHeight=iBPP=bEnc=0; - lImageSize=0; -} - - -TGAImg::~TGAImg() -{ - if(pImage) - { - delete [] pImage; - pImage=NULL; - } - - if(pPalette) - { - delete [] pPalette; - pPalette=NULL; - } - - if(pData) - { - delete [] pData; - pData=NULL; - } -} - - -int TGAImg::Load(char* szFilename) -{ - using namespace std; - ifstream fIn; - unsigned long ulSize; - int iRet; - - // Clear out any existing image and palette - if(pImage) - { - delete [] pImage; - pImage=NULL; - } - - if(pPalette) - { - delete [] pPalette; - pPalette=NULL; - } - - // Open the specified file - fIn.open(szFilename,ios::binary); - - if(fIn==NULL) - return IMG_ERR_NO_FILE; - - // Get file size - fIn.seekg(0,ios_base::end); - ulSize=fIn.tellg(); - fIn.seekg(0,ios_base::beg); - - // Allocate some space - // Check and clear pDat, just in case - if(pData) - delete [] pData; - - pData=new unsigned char[ulSize]; - - if(pData==NULL) - { - fIn.close(); - return IMG_ERR_MEM_FAIL; - } - - // Read the file into memory - fIn.read((char*)pData,ulSize); - - fIn.close(); - - // Process the header - iRet=ReadHeader(); - - if(iRet!=IMG_OK) - return iRet; - - switch(bEnc) - { - case 1: // Raw Indexed - { - // Check filesize against header values - if((lImageSize+18+pData[0]+768)>ulSize) - return IMG_ERR_BAD_FORMAT; - - // Double check image type field - if(pData[1]!=1) - return IMG_ERR_BAD_FORMAT; - - // Load image data - iRet=LoadRawData(); - if(iRet!=IMG_OK) - return iRet; - - // Load palette - iRet=LoadTgaPalette(); - if(iRet!=IMG_OK) - return iRet; - - break; - } - - case 2: // Raw RGB - { - // Check filesize against header values - if((lImageSize+18+pData[0])>ulSize) - return IMG_ERR_BAD_FORMAT; - - // Double check image type field - if(pData[1]!=0) - return IMG_ERR_BAD_FORMAT; - - // Load image data - iRet=LoadRawData(); - if(iRet!=IMG_OK) - return iRet; - - BGRtoRGB(); // Convert to RGB - break; - } - - case 9: // RLE Indexed - { - // Double check image type field - if(pData[1]!=1) - return IMG_ERR_BAD_FORMAT; - - // Load image data - iRet=LoadTgaRLEData(); - if(iRet!=IMG_OK) - return iRet; - - // Load palette - iRet=LoadTgaPalette(); - if(iRet!=IMG_OK) - return iRet; - - break; - } - - case 10: // RLE RGB - { - // Double check image type field - if(pData[1]!=0) - return IMG_ERR_BAD_FORMAT; - - // Load image data - iRet=LoadTgaRLEData(); - if(iRet!=IMG_OK) - return iRet; - - BGRtoRGB(); // Convert to RGB - break; - } - - default: - return IMG_ERR_UNSUPPORTED; - } - - // Check flip bit - if((pData[17] & 0x20)==0) - FlipImg(); - - // Release file memory - delete [] pData; - pData=NULL; - - return IMG_OK; -} - - -int TGAImg::ReadHeader() // Examine the header and populate our class attributes -{ - short ColMapStart,ColMapLen; - short x1,y1,x2,y2; - - if(pData==NULL) - return IMG_ERR_NO_FILE; - - if(pData[1]>1) // 0 (RGB) and 1 (Indexed) are the only types we know about - return IMG_ERR_UNSUPPORTED; - - bEnc=pData[2]; // Encoding flag 1 = Raw indexed image - // 2 = Raw RGB - // 3 = Raw greyscale - // 9 = RLE indexed - // 10 = RLE RGB - // 11 = RLE greyscale - // 32 & 33 Other compression, indexed - - if(bEnc>11) // We don't want 32 or 33 - return IMG_ERR_UNSUPPORTED; - - - // Get palette info - memcpy(&ColMapStart,&pData[3],2); - memcpy(&ColMapLen,&pData[5],2); - - // Reject indexed images if not a VGA palette (256 entries with 24 bits per entry) - if(pData[1]==1) // Indexed - { - if(ColMapStart!=0 || ColMapLen!=256 || pData[7]!=24) - return IMG_ERR_UNSUPPORTED; - } - - // Get image window and produce width & height values - memcpy(&x1,&pData[8],2); - memcpy(&y1,&pData[10],2); - memcpy(&x2,&pData[12],2); - memcpy(&y2,&pData[14],2); - - iWidth=(x2-x1); - iHeight=(y2-y1); - - if(iWidth<1 || iHeight<1) - return IMG_ERR_BAD_FORMAT; - - // Bits per Pixel - iBPP=pData[16]; - - // Check flip / interleave byte - if(pData[17]>32) // Interleaved data - return IMG_ERR_UNSUPPORTED; - - // Calculate image size - lImageSize=(iWidth * iHeight * (iBPP/8)); - - return IMG_OK; -} - - -int TGAImg::LoadRawData() // Load uncompressed image data -{ - short iOffset; - - if(pImage) // Clear old data if present - delete [] pImage; - - pImage=new unsigned char[lImageSize]; - - if(pImage==NULL) - return IMG_ERR_MEM_FAIL; - - iOffset=pData[0]+18; // Add header to ident field size - - if(pData[1]==1) // Indexed images - iOffset+=768; // Add palette offset - - memcpy(pImage,&pData[iOffset],lImageSize); - - return IMG_OK; -} - - -int TGAImg::LoadTgaRLEData() // Load RLE compressed image data -{ - short iOffset,iPixelSize; - unsigned char *pCur; - unsigned long Index=0; - unsigned char bLength,bLoop; - - // Calculate offset to image data - iOffset=pData[0]+18; - - // Add palette offset for indexed images - if(pData[1]==1) - iOffset+=768; - - // Get pixel size in bytes - iPixelSize=iBPP/8; - - // Set our pointer to the beginning of the image data - pCur=&pData[iOffset]; - - // Allocate space for the image data - if(pImage!=NULL) - delete [] pImage; - - pImage=new unsigned char[lImageSize]; - - if(pImage==NULL) - return IMG_ERR_MEM_FAIL; - - // Decode - while(Index