Panda3D
|
00001 // Filename: showBase.cxx 00002 // Created by: shochet (02Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifdef __APPLE__ 00016 // We have to include this before we include any Panda libraries, 00017 // because one of the things we pick up in Panda defines a macro for 00018 // TCP_NODELAY and friends, causing heartaches for the header files 00019 // picked up here. 00020 #include <Carbon/Carbon.h> 00021 extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); } 00022 #endif 00023 00024 #include "showBase.h" 00025 00026 #include "throw_event.h" 00027 #include "graphicsWindow.h" 00028 #include "renderBuffer.h" 00029 #include "camera.h" 00030 #include "graphicsPipeSelection.h" 00031 00032 #ifdef WIN32 00033 #include <windows.h> // For SystemParametersInfo() 00034 STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0}; 00035 TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0}; 00036 FILTERKEYS g_StartupFilterKeys = {sizeof(FILTERKEYS), 0}; 00037 #endif 00038 00039 ConfigureDef(config_showbase); 00040 ConfigureFn(config_showbase) { 00041 } 00042 00043 ConfigVariableSearchPath particle_path 00044 ("particle-path", 00045 PRC_DESC("The directories to search for particle files to be loaded.")); 00046 00047 ConfigVariableSearchPath & 00048 get_particle_path() { 00049 return particle_path; 00050 } 00051 00052 // Throw the "NewFrame" event in the C++ world. Some of the lerp code 00053 // depends on receiving this. 00054 void 00055 throw_new_frame() { 00056 throw_event("NewFrame"); 00057 } 00058 00059 // Returns the configure object for accessing config variables from a 00060 // scripting language. 00061 DConfig & 00062 get_config_showbase() { 00063 static DConfig config_showbase; 00064 return config_showbase; 00065 } 00066 00067 // Initialize the application for making a Gui-based app, such as wx. 00068 // At the moment, this is a no-op except on Mac. 00069 void 00070 init_app_for_gui() { 00071 #ifdef IS_OSX 00072 // Rudely bring the application to the foreground. This is 00073 // particularly important when running wx via the plugin, since the 00074 // plugin app is seen as separate from the browser app, even though 00075 // the user sees them as the same thing. We need to bring the 00076 // plugin app to the foreground to make its wx windows visible. 00077 activate_osx_application(); 00078 #endif 00079 00080 // We don't appear need to do the following, however, if we launch 00081 // the plugin correctly from its own bundle. 00082 /* 00083 static bool initted_for_gui = false; 00084 if (!initted_for_gui) { 00085 initted_for_gui = true; 00086 #ifdef IS_OSX 00087 ProcessSerialNumber psn; 00088 00089 GetCurrentProcess(&psn); 00090 CPSEnableForegroundOperation(&psn); 00091 SetFrontProcess(&psn); 00092 #endif // IS_OSX 00093 } 00094 */ 00095 } 00096 00097 // klunky interface since we cant pass array from python->C++ to use verify_window_sizes directly 00098 static int num_fullscreen_testsizes = 0; 00099 #define MAX_FULLSCREEN_TESTS 10 00100 static int fullscreen_testsizes[MAX_FULLSCREEN_TESTS * 2]; 00101 00102 void 00103 add_fullscreen_testsize(int xsize, int ysize) { 00104 if ((xsize == 0) && (ysize == 0)) { 00105 num_fullscreen_testsizes = 0; 00106 return; 00107 } 00108 00109 // silently fail if maxtests exceeded 00110 if (num_fullscreen_testsizes < MAX_FULLSCREEN_TESTS) { 00111 fullscreen_testsizes[num_fullscreen_testsizes * 2] = xsize; 00112 fullscreen_testsizes[num_fullscreen_testsizes * 2 + 1] = ysize; 00113 num_fullscreen_testsizes++; 00114 } 00115 } 00116 00117 void 00118 runtest_fullscreen_sizes(GraphicsWindow *win) { 00119 win->verify_window_sizes(num_fullscreen_testsizes, fullscreen_testsizes); 00120 } 00121 00122 bool 00123 query_fullscreen_testresult(int xsize, int ysize) { 00124 // stupid linear search that works ok as long as total tests are small 00125 int i; 00126 for (i=0; i < num_fullscreen_testsizes; i++) { 00127 if((fullscreen_testsizes[i * 2] == xsize) && 00128 (fullscreen_testsizes[i * 2 + 1] == ysize)) 00129 return true; 00130 } 00131 return false; 00132 } 00133 00134 void 00135 store_accessibility_shortcut_keys() { 00136 #ifdef WIN32 00137 SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0); 00138 SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0); 00139 SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0); 00140 #endif 00141 } 00142 00143 void 00144 allow_accessibility_shortcut_keys(bool allowKeys) { 00145 #ifdef WIN32 00146 if( allowKeys ) 00147 { 00148 // Restore StickyKeys/etc to original state and enable Windows key 00149 SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0); 00150 SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0); 00151 SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0); 00152 } else { 00153 // Disable StickyKeys/etc shortcuts but if the accessibility feature is on, 00154 // then leave the settings alone as its probably being usefully used 00155 00156 STICKYKEYS skOff = g_StartupStickyKeys; 00157 if( (skOff.dwFlags & SKF_STICKYKEYSON) == 0 ) 00158 { 00159 // Disable the hotkey and the confirmation 00160 skOff.dwFlags &= ~SKF_HOTKEYACTIVE; 00161 skOff.dwFlags &= ~SKF_CONFIRMHOTKEY; 00162 00163 SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &skOff, 0); 00164 } 00165 00166 TOGGLEKEYS tkOff = g_StartupToggleKeys; 00167 if( (tkOff.dwFlags & TKF_TOGGLEKEYSON) == 0 ) 00168 { 00169 // Disable the hotkey and the confirmation 00170 tkOff.dwFlags &= ~TKF_HOTKEYACTIVE; 00171 tkOff.dwFlags &= ~TKF_CONFIRMHOTKEY; 00172 00173 SystemParametersInfo(SPI_SETTOGGLEKEYS, sizeof(TOGGLEKEYS), &tkOff, 0); 00174 } 00175 00176 FILTERKEYS fkOff = g_StartupFilterKeys; 00177 if( (fkOff.dwFlags & FKF_FILTERKEYSON) == 0 ) 00178 { 00179 // Disable the hotkey and the confirmation 00180 fkOff.dwFlags &= ~FKF_HOTKEYACTIVE; 00181 fkOff.dwFlags &= ~FKF_CONFIRMHOTKEY; 00182 00183 SystemParametersInfo(SPI_SETFILTERKEYS, sizeof(FILTERKEYS), &fkOff, 0); 00184 } 00185 } 00186 #endif 00187 } 00188 00189 #if 0 00190 int TempGridZoneManager:: 00191 add_grid_zone(unsigned int x, 00192 unsigned int y, 00193 unsigned int width, 00194 unsigned int height, 00195 unsigned int zoneBase, 00196 unsigned int xZoneResolution, 00197 unsigned int yZoneResolution) { 00198 // zoneBase is the first zone in the grid (e.g. the upper left) 00199 // zoneResolution is the number of cells on each axsis. 00200 // returns the next available zoneBase (i.e. zoneBase+xZoneResolution*yZoneResolution) 00201 cerr<<"adding grid zone with a zoneBase of "<<zoneBase<<" and a zoneResolution of "<<zoneResolution; 00202 _grids.append(TempGridZoneManager::GridZone(x, y, width, height, zoneBase, xZoneResolution, yZoneResolution)); 00203 return zoneBase+xZoneResolution*yZoneResolution; 00204 } 00205 00206 void TempGridZoneManager::GridZone 00207 GridZone(unsigned int x, 00208 unsigned int y, 00209 unsigned int width, 00210 unsigned int height, 00211 unsigned int zoneBase, 00212 unsigned int xZoneResolution, 00213 unsigned int yZoneResolution) { 00214 _x=x; 00215 _y=y; 00216 _width=width; 00217 _height=heigth; 00218 _zoneBase=zoneBase; 00219 _xZoneResolution=xZoneResolution; 00220 _yZoneResolution=yZoneResolution; 00221 00222 // The cellVis is the number of cells radius that can 00223 // be seen, including the center cell. So, for a 5 x 5 00224 // visible area, the cellVis is 3. 00225 const float cellVis=3.0; 00226 unsigned int xMargine=(unsigned int)((float)width/(float)xZoneResolution*cellVis+0.5); 00227 unsigned int yMargine=(unsigned int)((float)height/(float)yZoneResolution*cellVis+0.5); 00228 _xMinVis=x-xMargine; 00229 _yMinVis=y-yMargine; 00230 _xMaxVis=x+width+xMargine; 00231 _yMaxVis=y+height+yMargine; 00232 } 00233 00234 void TempGridZoneManager:: 00235 get_grids(int x, int y) { 00236 TempGridZoneManager::ZoneSet canSee; 00237 TempGridZoneManager::GridSet::const_iterator i=_grids.begin(); 00238 for (; i!=_grids.end(); ++i) { 00239 if (x >= i._xMinVis && x < i._xMaxVis && y >= i._yMinVis && y < i._yMaxVis) { 00240 add_to_zone_list(i, x, y, canSee); 00241 } 00242 } 00243 } 00244 00245 void TempGridZoneManager:: 00246 add_to_zone_list(const TempGridZoneManager::GridZone &gridZone, 00247 unsigned int x, 00248 unsigned int y, 00249 TempGridZoneManager::ZoneSet &zoneSet) { 00250 unsigned int xRes=gridZone._xZoneResolution; 00251 unsigned int yRes=gridZone._yZoneResolution; 00252 float xP=((float)(x-gridZone._x))/gridZone._width; 00253 float yP=((float)(y-gridZone._y))/gridZone._height; 00254 int xCell=(int)(xP*xRes); 00255 int yCell=(int)(yP*yRes); 00256 00257 // range is how many cells can be seen in each direction: 00258 const int range=2; 00259 int yBegin=max(0, yCell-range); 00260 int yEnd=min(yRes, yCell+range); 00261 int xBegin=max(0, xCell-range); 00262 int xEnd=min(xRes, xCell+range); 00263 unsigned int zone=gridZone._zoneBase+yBegin*xRes+xBegin; 00264 00265 for (yCell=yBegin; yCell < yEnd; ++yCell) { 00266 for (xCell=xBegin; xCell < xEnd; ++xCell) { 00267 zoneSet.append(zone+xCell); 00268 } 00269 zone+=xRes; 00270 } 00271 } 00272 00273 int TempGridZoneManager:: 00274 get_zone_list(int x, int y, int resolution) { 00275 // x is a float in the range 0.0 to 1.0 00276 // y is a float in the range 0.0 to 1.0 00277 // resolution is the number of cells on each axsis. 00278 // returns a list of zone ids. 00279 // 00280 // Create a box of cell numbers, while clipping 00281 // to the edges of the set of cells. 00282 if (x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0) { 00283 return 0; 00284 } 00285 cerr<<"resolution="<<resolution; 00286 xCell=min(int(x*resolution), resolution-1) 00287 yCell=min(int(y*resolution), resolution-1) 00288 cell=yCell*resolution+xCell 00289 print "cell", cell, 00290 zone=zoneBase+cell 00291 print "zone", zone 00292 00293 zone=zone-2*resolution 00294 endZone=zone+5*resolution 00295 yCell=yCell-2 00296 while zone < endZone: 00297 if yCell >= 0 and yCell < resolution: 00298 if xCell > 1: 00299 zoneList.append(zone-2) 00300 zoneList.append(zone-1) 00301 elif xCell > 0: 00302 zoneList.append(zone-1) 00303 r.append(zone) 00304 if xCell < resolution-2: 00305 zoneList.append(zone+1) 00306 zoneList.append(zone+2) 00307 elif xCell < resolution-1: 00308 zoneList.append(zone+1) 00309 yCell+=1 00310 zone+=resolution 00311 return zoneList 00312 return 5; 00313 } 00314 #endif 00315