1 /* 2 PLIB - A Suite of Portable Game Libraries 3 Copyright (C) 1998,2002 Steve Baker 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public 7 License as published by the Free Software Foundation; either 8 version 2 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 19 For further information visit http://plib.sourceforge.net 20 21 $Id: ssgKeyFlier.h 1924 2004-04-06 13:32:26Z sjbaker $ 22 */ 23 24 25 #ifndef _SSG_KEYFLIER_H_ 26 #define _SSG_KEYFLIER_H_ 27 28 /***********************************************\ 29 * * 30 * SSG_KEYFLIER.H * 31 * * 32 * This file contains inline functions that * 33 * provide an ESIG-like keyboard-driven * 34 * flying carpet flight mode. * 35 * * 36 * Simply declare an instance of this class * 37 * somewhere in your program - and call the * 38 * 'incoming_keystroke' routine every time a * 39 * relevent character is typed - call the * 40 * 'update' function once per frame and the * 41 * 'get_coord' function whenever you need new * 42 * coordinates. Other handy functions are also * 43 * available. * 44 * * 45 * It's handy to use the 'Keyboard' class in * 46 * 'tty_port.h' to provide the incoming keys. * 47 * * 48 \***********************************************/ 49 50 typedef void (*queryFunc)(float,float,float,float,float,float) ; 51 typedef void (*exitFunc)(int) ; 52 53 class ssgKeyFlier 54 { 55 protected: 56 float tscale ; 57 float rscale ; 58 sgCoord curr_pos ; 59 sgCoord reset_pos ; 60 sgCoord last_pos ; 61 sgCoord curr_vel ; 62 sgCoord velocity ; 63 64 queryFunc query_action ; 65 exitFunc exit_action ; 66 67 public: ssgKeyFlier()68 ssgKeyFlier () 69 { 70 query_action = NULL ; 71 exit_action = NULL ; 72 73 tscale = 1.0 ; 74 rscale = 1.0 ; 75 sgZeroVec3 ( reset_pos.xyz ) ; sgZeroVec3 ( reset_pos.hpr ) ; 76 sgZeroVec3 ( last_pos.xyz ) ; sgZeroVec3 ( last_pos.hpr ) ; 77 sgZeroVec3 ( velocity.xyz ) ; sgZeroVec3 ( velocity.hpr ) ; 78 update () ; 79 } 80 set_query_action(queryFunc f)81 void set_query_action ( queryFunc f ) { query_action = f ; } set_exit_action(exitFunc f)82 void set_exit_action ( exitFunc f ) { exit_action = f ; } 83 stop_some()84 void stop_some () 85 { 86 velocity.xyz[0]=velocity.xyz[2]=0.0 ; 87 sgZeroVec3 ( velocity.hpr ) ; 88 update () ; 89 } 90 stop_all()91 void stop_all () 92 { 93 sgZeroVec3 ( velocity.xyz ) ; sgZeroVec3 ( velocity.hpr ) ; 94 update () ; 95 } 96 reset()97 void reset () 98 { 99 stop_all () ; 100 sgCopyVec3 ( last_pos.xyz, reset_pos.xyz ) ; 101 sgCopyVec3 ( last_pos.hpr, reset_pos.hpr ) ; 102 update () ; 103 } 104 get_scale_factors(float * translation_scale_factor,float * rotation_scale_factor)105 void get_scale_factors ( float *translation_scale_factor, float *rotation_scale_factor ) 106 { 107 if ( rotation_scale_factor != NULL ) 108 *rotation_scale_factor = rscale ; 109 110 if ( translation_scale_factor != NULL ) 111 *translation_scale_factor = tscale ; 112 } 113 114 /* Scale factors are in meters-per-update and degrees-per-update */ 115 set_scale_factors(float translation_scale_factor,float rotation_scale_factor)116 void set_scale_factors ( float translation_scale_factor, float rotation_scale_factor ) 117 { 118 rscale = rotation_scale_factor ; 119 tscale = translation_scale_factor ; 120 } 121 122 set_xyz_scale(float translation_scale_factor)123 void set_xyz_scale ( float translation_scale_factor ) 124 { 125 tscale = translation_scale_factor ; 126 } 127 128 set_hpr_scale(float rotation_scale_factor)129 void set_hpr_scale ( float rotation_scale_factor ) 130 { 131 rscale = rotation_scale_factor ; 132 } 133 134 set_reset(sgCoord * pos)135 void set_reset ( sgCoord *pos ) 136 { 137 sgCopyCoord ( & reset_pos, pos ) ; 138 } 139 get_velocity()140 sgCoord *get_velocity () 141 { 142 sgCopyCoord ( & curr_vel, & velocity ) ; 143 return & curr_vel ; 144 } 145 set_velocity(sgCoord * vel)146 void set_velocity ( sgCoord *vel ) 147 { 148 stop_all () ; 149 sgCopyCoord ( & velocity, vel ) ; 150 update () ; 151 } 152 get_coord()153 sgCoord *get_coord () 154 { 155 sgCopyCoord ( & curr_pos, & last_pos ) ; 156 return & curr_pos ; 157 } 158 159 void set_coord ( sgCoord *pos, int noStop = 0 ) 160 { 161 if ( ! noStop ) stop_all () ; 162 sgCopyCoord ( & last_pos, pos ) ; 163 update () ; 164 } 165 166 void show_help ( FILE *fd = stderr ) 167 { 168 fprintf ( fd, "ssgKeyFlier HELP.\n" ) ; 169 fprintf ( fd, "=================\n\n" ) ; 170 fprintf ( fd, "f : Faster - Make translational controls more sensitive.\n" ) ; 171 fprintf ( fd, "F : Faster - Make rotational controls more sensitive.\n" ) ; 172 fprintf ( fd, "s : Slower - Make translational controls less sensitive.\n" ) ; 173 fprintf ( fd, "S : Slower - Make rotational controls less sensitive.\n" ) ; 174 fprintf ( fd, "*,/: Same as 'f' and 's'.\n" ) ; 175 fprintf ( fd, "r/R: Reset - Reset eyepoint to pre-defined position.\n" ) ; 176 fprintf ( fd, "h/H: Help - Display this help message.\n" ) ; 177 fprintf ( fd, "^C : - Exit.\n" ) ; 178 fprintf ( fd, "? : - Where am I?\n" ) ; 179 fprintf ( fd, "5 : Stop rotation & slew 0 : Stop all movement.\n"); 180 fprintf ( fd, "2 : Pitch Up 8 : Pitch Down \n"); 181 fprintf ( fd, "4 : Yaw Left 6 : Yaw Right\n"); 182 fprintf ( fd, "7 : Roll Left 9 : Roll Right \n"); 183 fprintf ( fd, "1 : Translate Left. 3 : Translate Right\n"); 184 fprintf ( fd, "+/,: Translate Down - : Translate Up\n"); 185 fprintf ( fd, " . : Translate Backwards ENTER : Translate Forwards\n"); 186 fprintf ( fd, "[Note: Some of these controls may be overridden by the\n"); 187 fprintf ( fd, " application program.].\n"); 188 } 189 incoming_keystroke(char k)190 void incoming_keystroke ( char k ) 191 { 192 switch ( k ) 193 { 194 case 'h' : 195 case 'H' : show_help () ; break ; 196 case '/' : 197 case 'f' : tscale *= 2.0 ; break ; 198 case 'F' : rscale *= 2.0 ; break ; 199 case '*' : 200 case 's' : tscale /= 2.0 ; break ; 201 case 'S' : rscale /= 2.0 ; break ; 202 203 case 0x03: if ( exit_action ) exit_action( 0 ) ; exit ( 1 ) ; 204 205 case '?' : if ( query_action ) 206 query_action ( last_pos.xyz[0], last_pos.xyz[1], last_pos.xyz[2], 207 last_pos.hpr[0], last_pos.hpr[1], last_pos.hpr[2] ) ; 208 else 209 ulSetError ( UL_DEBUG, "ssgKeyFlier: XYZ=(%g,%g,%g), HPR=(%g,%g,%g)", 210 last_pos.xyz[0], last_pos.xyz[1], last_pos.xyz[2], 211 last_pos.hpr[0], last_pos.hpr[1], last_pos.hpr[2] ) ; 212 213 break ; 214 case 'r' : 215 case 'R' : reset () ; break ; 216 case '5' : stop_some () ; break ; 217 case '0' : stop_all () ; break ; 218 219 case '1' : velocity.xyz[0] -= tscale ; break ; 220 case '3' : velocity.xyz[0] += tscale ; break ; 221 case '.' : velocity.xyz[1] -= tscale ; break ; 222 case '\n' : 223 case '\r' : velocity.xyz[1] += tscale ; break ; 224 case '+' : velocity.xyz[2] -= tscale ; break ; 225 case '-' : velocity.xyz[2] += tscale ; break ; 226 227 case '6' : velocity.hpr[0] -= rscale ; break ; 228 case '4' : velocity.hpr[0] += rscale ; break ; 229 /* Kludge to try to prevent *exact* +/-90 degree pitch terms */ 230 case '8' : velocity.hpr[1] -= rscale+0.00001f ; break ; 231 case '2' : velocity.hpr[1] += rscale+0.00001f ; break ; 232 233 case '7' : velocity.hpr[2] -= rscale ; break ; 234 case '9' : velocity.hpr[2] += rscale ; break ; 235 } 236 } 237 isStationary()238 int isStationary () 239 { 240 return ( velocity.hpr[0] == 0.0 && 241 velocity.hpr[1] == 0.0 && 242 velocity.hpr[2] == 0.0 && 243 velocity.xyz[0] == 0.0 && 244 velocity.xyz[1] == 0.0 && 245 velocity.xyz[2] == 0.0 ) ; 246 } 247 update()248 virtual void update () 249 { 250 sgMat4 mat ; 251 sgMat4 result ; 252 sgMat4 delta ; 253 254 /* Form new matrix */ 255 256 sgMakeCoordMat4 ( delta, & velocity ) ; 257 sgMakeCoordMat4 ( mat , & last_pos ) ; 258 sgMultMat4 ( result, mat, delta ) ; 259 sgSetCoord ( &last_pos, result ) ; 260 } 261 } ; 262 263 264 #endif 265 266