From 86b1f0909b015d436c8fe471fa76e3f3214fb308 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 19 Nov 2012 15:20:24 -0800 Subject: [PATCH] More little housekeeping cleanups to main.cpp --- head.cpp | 119 +++++ .../UserInterfaceState.xcuserstate | Bin 101209 -> 101683 bytes main.cpp | 29 +- tga.h | 470 ------------------ 4 files changed, 123 insertions(+), 495 deletions(-) delete mode 100644 tga.h 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 a232612957bea21e610cb0ad66d91fb97d090527..b653b6168a2bc179a65c76fe4b742f86bf36cb02 100644 GIT binary patch delta 30848 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

|X|3F&bmJt3qg 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 Hxa9u;O))LD delta 30476 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 G!v6yV3c~gP 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