Converted "class fgVIEW" to "class FGView" and updated to make data
members private and make required accessor functions.
This commit is contained in:
parent
7acf7cd038
commit
f450f4a9af
16 changed files with 244 additions and 175 deletions
|
@ -257,7 +257,6 @@ void fgSkyInit( void ) {
|
||||||
void fgSkyRender( void ) {
|
void fgSkyRender( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgLIGHT *l;
|
fgLIGHT *l;
|
||||||
fgVIEW *v;
|
|
||||||
float inner_color[4];
|
float inner_color[4];
|
||||||
float middle_color[4];
|
float middle_color[4];
|
||||||
float outer_color[4];
|
float outer_color[4];
|
||||||
|
@ -266,7 +265,6 @@ void fgSkyRender( void ) {
|
||||||
|
|
||||||
f = current_aircraft.fdm_state;
|
f = current_aircraft.fdm_state;
|
||||||
l = &cur_light_params;
|
l = &cur_light_params;
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
// printf("Rendering the sky.\n");
|
// printf("Rendering the sky.\n");
|
||||||
|
|
||||||
|
@ -286,11 +284,10 @@ void fgSkyRender( void ) {
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
|
|
||||||
// Translate to view position
|
// Translate to view position
|
||||||
xglTranslatef( v->cur_zero_elev.x(),
|
Point3D zero_elev = current_view.get_cur_zero_elev();
|
||||||
v->cur_zero_elev.y(),
|
xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
|
||||||
v->cur_zero_elev.z() );
|
|
||||||
// printf(" Translated to %.2f %.2f %.2f\n",
|
// printf(" Translated to %.2f %.2f %.2f\n",
|
||||||
// v->cur_zero_elev.x, v->cur_zero_elev.y, v->cur_zero_elev.z );
|
// zero_elev.x, zero_elev.y, zero_elev.z );
|
||||||
|
|
||||||
// Rotate to proper orientation
|
// Rotate to proper orientation
|
||||||
// printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
|
// printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
|
||||||
|
@ -365,6 +362,10 @@ void fgSkyRender( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.17 1998/12/09 18:50:12 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.16 1998/12/05 15:54:03 curt
|
// Revision 1.16 1998/12/05 15:54:03 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -41,12 +41,6 @@
|
||||||
#include "pluto.hxx"
|
#include "pluto.hxx"
|
||||||
|
|
||||||
|
|
||||||
extern fgLIGHT cur_light_params;
|
|
||||||
extern fgTIME cur_time_params;
|
|
||||||
extern fgVIEW current_view;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SolarSystem
|
class SolarSystem
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -211,7 +211,6 @@ int fgStarsInit( void ) {
|
||||||
// Draw the Stars
|
// Draw the Stars
|
||||||
void fgStarsRender( void ) {
|
void fgStarsRender( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgVIEW *v;
|
|
||||||
fgLIGHT *l;
|
fgLIGHT *l;
|
||||||
fgTIME *t;
|
fgTIME *t;
|
||||||
int i;
|
int i;
|
||||||
|
@ -219,7 +218,6 @@ void fgStarsRender( void ) {
|
||||||
f = current_aircraft.fdm_state;
|
f = current_aircraft.fdm_state;
|
||||||
l = &cur_light_params;
|
l = &cur_light_params;
|
||||||
t = &cur_time_params;
|
t = &cur_time_params;
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
// FG_PI_2 + 0.1 is about 6 degrees after sundown and before sunrise
|
// FG_PI_2 + 0.1 is about 6 degrees after sundown and before sunrise
|
||||||
|
|
||||||
|
@ -256,6 +254,10 @@ void fgStarsRender( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.25 1998/12/09 18:50:15 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.24 1998/12/05 15:54:04 curt
|
// Revision 1.24 1998/12/05 15:54:04 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -217,11 +217,7 @@ double get_sideslip( void )
|
||||||
|
|
||||||
double get_frame_rate( void )
|
double get_frame_rate( void )
|
||||||
{
|
{
|
||||||
fgGENERAL *pgeneral;
|
return general.frame_rate;
|
||||||
|
|
||||||
pgeneral = &general;
|
|
||||||
|
|
||||||
return pgeneral->frame_rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_fov( void )
|
double get_fov( void )
|
||||||
|
@ -231,16 +227,12 @@ double get_fov( void )
|
||||||
|
|
||||||
double get_vfc_ratio( void )
|
double get_vfc_ratio( void )
|
||||||
{
|
{
|
||||||
fgVIEW *pview;
|
return current_view.get_vfc_ratio();
|
||||||
|
|
||||||
pview = ¤t_view;
|
|
||||||
|
|
||||||
return pview->vfc_ratio;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_vfc_tris_drawn ( void )
|
double get_vfc_tris_drawn ( void )
|
||||||
{
|
{
|
||||||
return current_view.tris_rendered;
|
return current_view.get_tris_rendered();
|
||||||
}
|
}
|
||||||
|
|
||||||
double get_climb_rate( void )
|
double get_climb_rate( void )
|
||||||
|
@ -289,10 +281,6 @@ bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
|
||||||
|
|
||||||
|
|
||||||
void fgCockpitUpdate( void ) {
|
void fgCockpitUpdate( void ) {
|
||||||
fgVIEW *pview;
|
|
||||||
|
|
||||||
pview = ¤t_view;
|
|
||||||
|
|
||||||
FG_LOG( FG_COCKPIT, FG_DEBUG,
|
FG_LOG( FG_COCKPIT, FG_DEBUG,
|
||||||
"Cockpit: code " << ac_cockpit->code() << " status "
|
"Cockpit: code " << ac_cockpit->code() << " status "
|
||||||
<< ac_cockpit->status() );
|
<< ac_cockpit->status() );
|
||||||
|
@ -304,14 +292,21 @@ void fgCockpitUpdate( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( current_options.get_panel_status() &&
|
if ( current_options.get_panel_status() &&
|
||||||
(fabs(pview->view_offset) < 0.2) ) {
|
(fabs( current_view.get_view_offset() ) < 0.2) )
|
||||||
xglViewport(0, 0, pview->winWidth, pview->winHeight);
|
{
|
||||||
|
xglViewport( 0, 0,
|
||||||
|
current_view.get_winWidth(),
|
||||||
|
current_view.get_winHeight() );
|
||||||
fgPanelUpdate();
|
fgPanelUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.26 1998/12/09 18:50:19 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.25 1998/12/05 15:54:07 curt
|
// Revision 1.25 1998/12/05 15:54:07 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -299,14 +299,11 @@ static IMAGE *ImageLoad(char *fileName)
|
||||||
|
|
||||||
// Beginning of the "panel-code"
|
// Beginning of the "panel-code"
|
||||||
void fgPanelInit ( void ) {
|
void fgPanelInit ( void ) {
|
||||||
fgVIEW *v;
|
|
||||||
string tpath;
|
string tpath;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
v = ¤t_view;
|
Xzoom = (float)((float)(current_view.get_winWidth())/1024.0);
|
||||||
|
Yzoom = (float)((float)(current_view.get_winHeight())/768.0);
|
||||||
Xzoom = (float)((float)(current_view.winWidth)/1024);
|
|
||||||
Yzoom = (float)((float)(current_view.winHeight)/768);
|
|
||||||
|
|
||||||
pointer[1].XPos = 357;
|
pointer[1].XPos = 357;
|
||||||
pointer[1].YPos = 167;
|
pointer[1].YPos = 167;
|
||||||
|
@ -420,15 +417,13 @@ CreatePointer(&pointer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgPanelReInit( int x, int y, int finx, int finy){
|
void fgPanelReInit( int x, int y, int finx, int finy){
|
||||||
fgVIEW *v;
|
|
||||||
fgOPTIONS *o;
|
fgOPTIONS *o;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
o = ¤t_options;
|
o = ¤t_options;
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
Xzoom = (float)((float)(current_view.winWidth)/1024);
|
Xzoom = (float)((float)(current_view.get_winWidth())/1024);
|
||||||
Yzoom = (float)((float)(current_view.winHeight)/768);
|
Yzoom = (float)((float)(current_view.get_winHeight())/768);
|
||||||
|
|
||||||
xglMatrixMode(GL_PROJECTION);
|
xglMatrixMode(GL_PROJECTION);
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
|
@ -451,7 +446,6 @@ void fgPanelReInit( int x, int y, int finx, int finy){
|
||||||
}
|
}
|
||||||
|
|
||||||
void fgPanelUpdate ( void ) {
|
void fgPanelUpdate ( void ) {
|
||||||
fgVIEW *v;
|
|
||||||
float alpha;
|
float alpha;
|
||||||
double pitch;
|
double pitch;
|
||||||
double roll;
|
double roll;
|
||||||
|
@ -462,7 +456,6 @@ void fgPanelUpdate ( void ) {
|
||||||
var[1] = get_altitude();
|
var[1] = get_altitude();
|
||||||
var[2] = get_aoa(); // A placeholder. It should be the vertical speed once.
|
var[2] = get_aoa(); // A placeholder. It should be the vertical speed once.
|
||||||
var[3] = get_throttleval();
|
var[3] = get_throttleval();
|
||||||
v = ¤t_view;
|
|
||||||
xglMatrixMode(GL_PROJECTION);
|
xglMatrixMode(GL_PROJECTION);
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
xglLoadIdentity();
|
xglLoadIdentity();
|
||||||
|
@ -671,6 +664,10 @@ printf(" %f %f %f %f \n", mvmatrix[12], mvmatrix[13], mvmatrix[14], mvma
|
||||||
}
|
}
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.12 1998/12/09 18:50:20 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.11 1998/11/11 00:19:27 curt
|
// Revision 1.11 1998/11/11 00:19:27 curt
|
||||||
// Updated comment delimeter to C++ style.
|
// Updated comment delimeter to C++ style.
|
||||||
//
|
//
|
||||||
|
|
|
@ -71,7 +71,7 @@ static void local_update_sky_and_lighting_params( void ) {
|
||||||
void GLUTkey(unsigned char k, int x, int y) {
|
void GLUTkey(unsigned char k, int x, int y) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgTIME *t;
|
fgTIME *t;
|
||||||
fgVIEW *v;
|
FGView *v;
|
||||||
FGWeather *w;
|
FGWeather *w;
|
||||||
float fov, tmp;
|
float fov, tmp;
|
||||||
static bool winding_ccw = true;
|
static bool winding_ccw = true;
|
||||||
|
@ -109,28 +109,28 @@ void GLUTkey(unsigned char k, int x, int y) {
|
||||||
fgAPToggleTerrainFollow();
|
fgAPToggleTerrainFollow();
|
||||||
return;
|
return;
|
||||||
case 49: // numeric keypad 1
|
case 49: // numeric keypad 1
|
||||||
v->goal_view_offset = FG_PI * 0.75;
|
v->set_goal_view_offset( FG_PI * 0.75 );
|
||||||
return;
|
return;
|
||||||
case 50: // numeric keypad 2
|
case 50: // numeric keypad 2
|
||||||
v->goal_view_offset = FG_PI;
|
v->set_goal_view_offset( FG_PI );
|
||||||
return;
|
return;
|
||||||
case 51: // numeric keypad 3
|
case 51: // numeric keypad 3
|
||||||
v->goal_view_offset = FG_PI * 1.25;
|
v->set_goal_view_offset( FG_PI * 1.25 );
|
||||||
return;
|
return;
|
||||||
case 52: // numeric keypad 4
|
case 52: // numeric keypad 4
|
||||||
v->goal_view_offset = FG_PI * 0.50;
|
v->set_goal_view_offset( FG_PI * 0.50 );
|
||||||
return;
|
return;
|
||||||
case 54: // numeric keypad 6
|
case 54: // numeric keypad 6
|
||||||
v->goal_view_offset = FG_PI * 1.50;
|
v->set_goal_view_offset( FG_PI * 1.50 );
|
||||||
return;
|
return;
|
||||||
case 55: // numeric keypad 7
|
case 55: // numeric keypad 7
|
||||||
v->goal_view_offset = FG_PI * 0.25;
|
v->set_goal_view_offset( FG_PI * 0.25 );
|
||||||
return;
|
return;
|
||||||
case 56: // numeric keypad 8
|
case 56: // numeric keypad 8
|
||||||
v->goal_view_offset = 0.00;
|
v->set_goal_view_offset( 0.00 );
|
||||||
return;
|
return;
|
||||||
case 57: // numeric keypad 9
|
case 57: // numeric keypad 9
|
||||||
v->goal_view_offset = FG_PI * 1.75;
|
v->set_goal_view_offset( FG_PI * 1.75 );
|
||||||
return;
|
return;
|
||||||
case 72: // H key
|
case 72: // H key
|
||||||
// status = current_options.get_hud_status();
|
// status = current_options.get_hud_status();
|
||||||
|
@ -164,7 +164,7 @@ void GLUTkey(unsigned char k, int x, int y) {
|
||||||
fov = FG_FOV_MAX;
|
fov = FG_FOV_MAX;
|
||||||
}
|
}
|
||||||
current_options.set_fov(fov);
|
current_options.set_fov(fov);
|
||||||
v->update_fov = TRUE;
|
v->set_update_fov( true );
|
||||||
return;
|
return;
|
||||||
case 90: // Z key
|
case 90: // Z key
|
||||||
tmp = w->get_visibility(); // in meters
|
tmp = w->get_visibility(); // in meters
|
||||||
|
@ -250,7 +250,7 @@ void GLUTkey(unsigned char k, int x, int y) {
|
||||||
fov = FG_FOV_MIN;
|
fov = FG_FOV_MIN;
|
||||||
}
|
}
|
||||||
current_options.set_fov(fov);
|
current_options.set_fov(fov);
|
||||||
v->update_fov = TRUE;
|
v->set_update_fov( true );
|
||||||
return;
|
return;
|
||||||
case 122: // z key
|
case 122: // z key
|
||||||
tmp = w->get_visibility(); // in meters
|
tmp = w->get_visibility(); // in meters
|
||||||
|
@ -271,7 +271,7 @@ void GLUTkey(unsigned char k, int x, int y) {
|
||||||
|
|
||||||
// Handle "special" keyboard events
|
// Handle "special" keyboard events
|
||||||
void GLUTspecialkey(int k, int x, int y) {
|
void GLUTspecialkey(int k, int x, int y) {
|
||||||
fgVIEW *v;
|
FGView *v;
|
||||||
|
|
||||||
v = ¤t_view;
|
v = ¤t_view;
|
||||||
|
|
||||||
|
@ -282,28 +282,28 @@ void GLUTspecialkey(int k, int x, int y) {
|
||||||
FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
|
FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case GLUT_KEY_END: // numeric keypad 1
|
case GLUT_KEY_END: // numeric keypad 1
|
||||||
v->goal_view_offset = FG_PI * 0.75;
|
v->set_goal_view_offset( FG_PI * 0.75 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_DOWN: // numeric keypad 2
|
case GLUT_KEY_DOWN: // numeric keypad 2
|
||||||
v->goal_view_offset = FG_PI;
|
v->set_goal_view_offset( FG_PI );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_PAGE_DOWN: // numeric keypad 3
|
case GLUT_KEY_PAGE_DOWN: // numeric keypad 3
|
||||||
v->goal_view_offset = FG_PI * 1.25;
|
v->set_goal_view_offset( FG_PI * 1.25 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_LEFT: // numeric keypad 4
|
case GLUT_KEY_LEFT: // numeric keypad 4
|
||||||
v->goal_view_offset = FG_PI * 0.50;
|
v->set_goal_view_offset( FG_PI * 0.50 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_RIGHT: // numeric keypad 6
|
case GLUT_KEY_RIGHT: // numeric keypad 6
|
||||||
v->goal_view_offset = FG_PI * 1.50;
|
v->set_goal_view_offset( FG_PI * 1.50 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_HOME: // numeric keypad 7
|
case GLUT_KEY_HOME: // numeric keypad 7
|
||||||
v->goal_view_offset = FG_PI * 0.25;
|
v->set_goal_view_offset( FG_PI * 0.25 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_UP: // numeric keypad 8
|
case GLUT_KEY_UP: // numeric keypad 8
|
||||||
v->goal_view_offset = 0.00;
|
v->set_goal_view_offset( 0.00 );
|
||||||
return;
|
return;
|
||||||
case GLUT_KEY_PAGE_UP: // numeric keypad 9
|
case GLUT_KEY_PAGE_UP: // numeric keypad 9
|
||||||
v->goal_view_offset = FG_PI * 1.75;
|
v->set_goal_view_offset( FG_PI * 1.75 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -386,6 +386,10 @@ void GLUTspecialkey(int k, int x, int y) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.37 1998/12/09 18:50:22 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.36 1998/12/06 13:51:20 curt
|
// Revision 1.36 1998/12/06 13:51:20 curt
|
||||||
// Turned "struct fgWEATHER" into "class FGWeather".
|
// Turned "struct fgWEATHER" into "class FGWeather".
|
||||||
//
|
//
|
||||||
|
|
|
@ -182,9 +182,7 @@ static void fgUpdateInstrViewParams( void ) {
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
fgVIEW *v;
|
fgVIEW *v = ¤t_view;
|
||||||
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
|
xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
|
||||||
|
|
||||||
|
@ -226,10 +224,11 @@ static void fgUpdateInstrViewParams( void ) {
|
||||||
|
|
||||||
// Update all Visuals (redraws anything graphics related)
|
// Update all Visuals (redraws anything graphics related)
|
||||||
static void fgRenderFrame( void ) {
|
static void fgRenderFrame( void ) {
|
||||||
FGState *f;
|
FGState *f = current_aircraft.fdm_state;
|
||||||
fgLIGHT *l;
|
fgLIGHT *l = &cur_light_params;
|
||||||
fgTIME *t;
|
fgTIME *t = &cur_time_params;
|
||||||
fgVIEW *v;
|
FGView *v = ¤t_view;
|
||||||
|
|
||||||
double angle;
|
double angle;
|
||||||
static int iteration = 0;
|
static int iteration = 0;
|
||||||
// GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
|
// GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
|
||||||
|
@ -237,11 +236,6 @@ static void fgRenderFrame( void ) {
|
||||||
GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
|
GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
|
||||||
GLbitfield clear_mask;
|
GLbitfield clear_mask;
|
||||||
|
|
||||||
f = current_aircraft.fdm_state;
|
|
||||||
l = &cur_light_params;
|
|
||||||
t = &cur_time_params;
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
if ( idle_state != 1000 ) {
|
if ( idle_state != 1000 ) {
|
||||||
// still initializing, draw the splash screen
|
// still initializing, draw the splash screen
|
||||||
if ( current_options.get_splash_screen() == 1 ) {
|
if ( current_options.get_splash_screen() == 1 ) {
|
||||||
|
@ -299,7 +293,8 @@ static void fgRenderFrame( void ) {
|
||||||
// setup transformation for drawing astronomical objects
|
// setup transformation for drawing astronomical objects
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
// Translate to view position
|
// Translate to view position
|
||||||
xglTranslatef( v->view_pos.x(), v->view_pos.y(), v->view_pos.z() );
|
Point3D view_pos = v->get_view_pos();
|
||||||
|
xglTranslatef( view_pos.x(), view_pos.y(), view_pos.z() );
|
||||||
// Rotate based on gst (sidereal time)
|
// Rotate based on gst (sidereal time)
|
||||||
// note: constant should be 15.041085, Curt thought it was 15
|
// note: constant should be 15.041085, Curt thought it was 15
|
||||||
angle = t->gst * 15.041085;
|
angle = t->gst * 15.041085;
|
||||||
|
@ -346,6 +341,7 @@ static void fgRenderFrame( void ) {
|
||||||
fgTileMgrRender();
|
fgTileMgrRender();
|
||||||
|
|
||||||
xglDisable( GL_TEXTURE_2D );
|
xglDisable( GL_TEXTURE_2D );
|
||||||
|
xglDisable( GL_FOG );
|
||||||
|
|
||||||
if ( (iteration == 0) && (current_options.get_panel_status()) ) {
|
if ( (iteration == 0) && (current_options.get_panel_status()) ) {
|
||||||
// Did we run this loop before ?? ...and do we need the panel ??
|
// Did we run this loop before ?? ...and do we need the panel ??
|
||||||
|
@ -361,6 +357,7 @@ static void fgRenderFrame( void ) {
|
||||||
xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||||
puDisplay();
|
puDisplay();
|
||||||
xglDisable ( GL_BLEND ) ;
|
xglDisable ( GL_BLEND ) ;
|
||||||
|
xglEnable( GL_FOG );
|
||||||
}
|
}
|
||||||
|
|
||||||
xglutSwapBuffers();
|
xglutSwapBuffers();
|
||||||
|
@ -369,17 +366,12 @@ static void fgRenderFrame( void ) {
|
||||||
|
|
||||||
// Update internal time dependent calculations (i.e. flight model)
|
// Update internal time dependent calculations (i.e. flight model)
|
||||||
void fgUpdateTimeDepCalcs(int multi_loop) {
|
void fgUpdateTimeDepCalcs(int multi_loop) {
|
||||||
FGState *f;
|
FGState *f = current_aircraft.fdm_state;
|
||||||
fgLIGHT *l;
|
fgLIGHT *l = &cur_light_params;
|
||||||
fgTIME *t;
|
fgTIME *t = &cur_time_params;
|
||||||
fgVIEW *v;
|
FGView *v = ¤t_view;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
f = current_aircraft.fdm_state;
|
|
||||||
l = &cur_light_params;
|
|
||||||
t = &cur_time_params;
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
// update the flight model
|
// update the flight model
|
||||||
if ( multi_loop < 0 ) {
|
if ( multi_loop < 0 ) {
|
||||||
multi_loop = DEFAULT_MULTILOOP;
|
multi_loop = DEFAULT_MULTILOOP;
|
||||||
|
@ -399,33 +391,34 @@ void fgUpdateTimeDepCalcs(int multi_loop) {
|
||||||
|
|
||||||
// update the view angle
|
// update the view angle
|
||||||
for ( i = 0; i < multi_loop; i++ ) {
|
for ( i = 0; i < multi_loop; i++ ) {
|
||||||
if ( fabs(v->goal_view_offset - v->view_offset) < 0.05 ) {
|
if ( fabs(v->get_goal_view_offset() - v->get_view_offset()) < 0.05 ) {
|
||||||
v->view_offset = v->goal_view_offset;
|
v->set_view_offset( v->get_goal_view_offset() );
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
// move v->view_offset towards v->goal_view_offset
|
// move v->view_offset towards v->goal_view_offset
|
||||||
if ( v->goal_view_offset > v->view_offset ) {
|
if ( v->get_goal_view_offset() > v->get_view_offset() ) {
|
||||||
if ( v->goal_view_offset - v->view_offset < FG_PI ) {
|
if ( v->get_goal_view_offset() - v->get_view_offset() < FG_PI ){
|
||||||
v->view_offset += 0.01;
|
v->inc_view_offset( 0.01 );
|
||||||
} else {
|
} else {
|
||||||
v->view_offset -= 0.01;
|
v->inc_view_offset( -0.01 );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( v->view_offset - v->goal_view_offset < FG_PI ) {
|
if ( v->get_view_offset() - v->get_goal_view_offset() < FG_PI ){
|
||||||
v->view_offset -= 0.01;
|
v->inc_view_offset( -0.01 );
|
||||||
} else {
|
} else {
|
||||||
v->view_offset += 0.01;
|
v->inc_view_offset( 0.01 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( v->view_offset > FG_2PI ) {
|
if ( v->get_view_offset() > FG_2PI ) {
|
||||||
v->view_offset -= FG_2PI;
|
v->inc_view_offset( -FG_2PI );
|
||||||
} else if ( v->view_offset < 0 ) {
|
} else if ( v->get_view_offset() < 0 ) {
|
||||||
v->view_offset += FG_2PI;
|
v->inc_view_offset( FG_2PI );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double tmp = -(l->sun_rotation + FG_PI) - (f->get_Psi() - v->view_offset);
|
double tmp = -(l->sun_rotation + FG_PI)
|
||||||
|
- (f->get_Psi() - v->get_view_offset() );
|
||||||
while ( tmp < 0.0 ) {
|
while ( tmp < 0.0 ) {
|
||||||
tmp += FG_2PI;
|
tmp += FG_2PI;
|
||||||
}
|
}
|
||||||
|
@ -792,23 +785,21 @@ static void fgIdleFunction ( void ) {
|
||||||
|
|
||||||
// Handle new window size or exposure
|
// Handle new window size or exposure
|
||||||
static void fgReshape( int width, int height ) {
|
static void fgReshape( int width, int height ) {
|
||||||
fgVIEW *v;
|
FGView *v = ¤t_view;
|
||||||
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
// Do this so we can call fgReshape(0,0) ourselves without having
|
// Do this so we can call fgReshape(0,0) ourselves without having
|
||||||
// to know what the values of width & height are.
|
// to know what the values of width & height are.
|
||||||
if ( (height > 0) && (width > 0) ) {
|
if ( (height > 0) && (width > 0) ) {
|
||||||
if ( ! current_options.get_panel_status() ) {
|
if ( ! current_options.get_panel_status() ) {
|
||||||
v->win_ratio = (GLfloat) width / (GLfloat) height;
|
v->set_win_ratio( (GLfloat) width / (GLfloat) height );
|
||||||
} else {
|
} else {
|
||||||
v->win_ratio = (GLfloat) width / ((GLfloat) (height)*0.4232);
|
v->set_win_ratio( (GLfloat) width / ((GLfloat) (height)*0.4232) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v->winWidth = width;
|
v->set_winWidth( width );
|
||||||
v->winHeight = height;
|
v->set_winHeight( height );
|
||||||
v->update_fov = true;
|
v->set_update_fov( true );
|
||||||
|
|
||||||
// Inform gl of our view window size (now handled elsewhere)
|
// Inform gl of our view window size (now handled elsewhere)
|
||||||
// xglViewport(0, 0, (GLint)width, (GLint)height);
|
// xglViewport(0, 0, (GLint)width, (GLint)height);
|
||||||
|
@ -1012,6 +1003,10 @@ int main( int argc, char **argv ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.75 1998/12/09 18:50:23 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.74 1998/12/06 14:52:54 curt
|
// Revision 1.74 1998/12/06 14:52:54 curt
|
||||||
// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
|
// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
|
||||||
// being calculated correctly at the beginning causing the first terrain
|
// being calculated correctly at the beginning causing the first terrain
|
||||||
|
|
|
@ -154,16 +154,12 @@ int fgInitGeneral( void ) {
|
||||||
// Returns non-zero if a problem encountered.
|
// Returns non-zero if a problem encountered.
|
||||||
int fgInitSubsystems( void )
|
int fgInitSubsystems( void )
|
||||||
{
|
{
|
||||||
FGState *f;
|
FGState *f; // assigned later
|
||||||
fgLIGHT *l;
|
fgLIGHT *l = &cur_light_params;
|
||||||
fgTIME *t;
|
fgTIME *t = &cur_time_params;
|
||||||
fgVIEW *v;
|
FGView *v = ¤t_view;
|
||||||
Point3D geod_pos, tmp_abs_view_pos;
|
Point3D geod_pos, tmp_abs_view_pos;
|
||||||
|
|
||||||
l = &cur_light_params;
|
|
||||||
t = &cur_time_params;
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
|
FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
|
||||||
FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
|
FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
|
||||||
|
|
||||||
|
@ -282,7 +278,7 @@ int fgInitSubsystems( void )
|
||||||
v->Init();
|
v->Init();
|
||||||
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
|
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
|
||||||
v->UpdateViewMath(f);
|
v->UpdateViewMath(f);
|
||||||
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->abs_view_pos );
|
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->get_abs_view_pos());
|
||||||
v->UpdateWorldToEye(f);
|
v->UpdateWorldToEye(f);
|
||||||
|
|
||||||
// Build the solar system
|
// Build the solar system
|
||||||
|
@ -385,6 +381,10 @@ int fgInitSubsystems( void )
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.58 1998/12/09 18:50:25 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.57 1998/12/06 14:52:56 curt
|
// Revision 1.57 1998/12/06 14:52:56 curt
|
||||||
// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
|
// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
|
||||||
// being calculated correctly at the beginning causing the first terrain
|
// being calculated correctly at the beginning causing the first terrain
|
||||||
|
|
|
@ -97,10 +97,10 @@ void fgSplashUpdate ( double progress ) {
|
||||||
int xsize = 480;
|
int xsize = 480;
|
||||||
int ysize = 380;
|
int ysize = 380;
|
||||||
|
|
||||||
xmin = (current_view.winWidth - xsize) / 2;
|
xmin = (current_view.get_winWidth() - xsize) / 2;
|
||||||
xmax = xmin + xsize;
|
xmax = xmin + xsize;
|
||||||
|
|
||||||
ymin = (current_view.winHeight - ysize) / 2;
|
ymin = (current_view.get_winHeight() - ysize) / 2;
|
||||||
ymax = ymin + ysize;
|
ymax = ymin + ysize;
|
||||||
|
|
||||||
// first clear the screen;
|
// first clear the screen;
|
||||||
|
@ -111,7 +111,7 @@ void fgSplashUpdate ( double progress ) {
|
||||||
xglMatrixMode(GL_PROJECTION);
|
xglMatrixMode(GL_PROJECTION);
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
xglLoadIdentity();
|
xglLoadIdentity();
|
||||||
gluOrtho2D(0, current_view.winWidth, 0, current_view.winHeight);
|
gluOrtho2D(0, current_view.get_winWidth(), 0, current_view.get_winHeight());
|
||||||
xglMatrixMode(GL_MODELVIEW);
|
xglMatrixMode(GL_MODELVIEW);
|
||||||
xglPushMatrix();
|
xglPushMatrix();
|
||||||
xglLoadIdentity();
|
xglLoadIdentity();
|
||||||
|
@ -149,6 +149,10 @@ void fgSplashUpdate ( double progress ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.9 1998/12/09 18:50:26 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.8 1998/11/16 14:00:05 curt
|
// Revision 1.8 1998/11/16 14:00:05 curt
|
||||||
// Added pow() macro bug work around.
|
// Added pow() macro bug work around.
|
||||||
// Added support for starting FGFS at various resolutions.
|
// Added support for starting FGFS at various resolutions.
|
||||||
|
|
|
@ -43,16 +43,16 @@
|
||||||
|
|
||||||
|
|
||||||
// This is a record containing current view parameters
|
// This is a record containing current view parameters
|
||||||
fgVIEW current_view;
|
FGView current_view;
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
fgVIEW::fgVIEW( void ) {
|
FGView::FGView( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialize a view structure
|
// Initialize a view structure
|
||||||
void fgVIEW::Init( void ) {
|
void FGView::Init( void ) {
|
||||||
FG_LOG( FG_VIEW, FG_INFO, "Initializing View parameters" );
|
FG_LOG( FG_VIEW, FG_INFO, "Initializing View parameters" );
|
||||||
|
|
||||||
view_offset = 0.0;
|
view_offset = 0.0;
|
||||||
|
@ -66,7 +66,7 @@ void fgVIEW::Init( void ) {
|
||||||
|
|
||||||
|
|
||||||
// Update the field of view parameters
|
// Update the field of view parameters
|
||||||
void fgVIEW::UpdateFOV( fgOPTIONS *o ) {
|
void FGView::UpdateFOV( fgOPTIONS *o ) {
|
||||||
double fov, theta_x, theta_y;
|
double fov, theta_x, theta_y;
|
||||||
|
|
||||||
fov = o->get_fov();
|
fov = o->get_fov();
|
||||||
|
@ -101,7 +101,7 @@ void fgVIEW::UpdateFOV( fgOPTIONS *o ) {
|
||||||
// Basically, this is a modified version of the Mesa gluLookAt()
|
// Basically, this is a modified version of the Mesa gluLookAt()
|
||||||
// function that's been modified slightly so we can capture the
|
// function that's been modified slightly so we can capture the
|
||||||
// result before sending it off to OpenGL land.
|
// result before sending it off to OpenGL land.
|
||||||
void fgVIEW::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
|
void FGView::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
|
||||||
GLdouble centerx, GLdouble centery, GLdouble centerz,
|
GLdouble centerx, GLdouble centery, GLdouble centerz,
|
||||||
GLdouble upx, GLdouble upy, GLdouble upz ) {
|
GLdouble upx, GLdouble upy, GLdouble upz ) {
|
||||||
GLdouble *m;
|
GLdouble *m;
|
||||||
|
@ -184,7 +184,7 @@ void fgVIEW::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
|
||||||
|
|
||||||
|
|
||||||
// Update the view volume, position, and orientation
|
// Update the view volume, position, and orientation
|
||||||
void fgVIEW::UpdateViewParams( void ) {
|
void FGView::UpdateViewParams( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgLIGHT *l;
|
fgLIGHT *l;
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ void fgVIEW::UpdateViewParams( void ) {
|
||||||
|
|
||||||
|
|
||||||
// Update the view parameters
|
// Update the view parameters
|
||||||
void fgVIEW::UpdateViewMath( FGState *f ) {
|
void FGView::UpdateViewMath( FGState *f ) {
|
||||||
Point3D p;
|
Point3D p;
|
||||||
MAT3vec vec, forward, v0, minus_z;
|
MAT3vec vec, forward, v0, minus_z;
|
||||||
MAT3mat R, TMP, UP, LOCAL, VIEW;
|
MAT3mat R, TMP, UP, LOCAL, VIEW;
|
||||||
|
@ -426,7 +426,7 @@ void fgVIEW::UpdateViewMath( FGState *f ) {
|
||||||
|
|
||||||
// Update the "World to Eye" transformation matrix
|
// Update the "World to Eye" transformation matrix
|
||||||
// This is most useful for view frustum culling
|
// This is most useful for view frustum culling
|
||||||
void fgVIEW::UpdateWorldToEye( FGState *f ) {
|
void FGView::UpdateWorldToEye( FGState *f ) {
|
||||||
MAT3mat R_Phi, R_Theta, R_Psi, R_Lat, R_Lon, T_view;
|
MAT3mat R_Phi, R_Theta, R_Psi, R_Lat, R_Lon, T_view;
|
||||||
MAT3mat TMP;
|
MAT3mat TMP;
|
||||||
MAT3hvec vec;
|
MAT3hvec vec;
|
||||||
|
@ -550,7 +550,7 @@ void fgVIEW::UpdateWorldToEye( FGState *f ) {
|
||||||
// Olson curt@me.umn.edu and Norman Vine nhv@yahoo.com with 'gentle
|
// Olson curt@me.umn.edu and Norman Vine nhv@yahoo.com with 'gentle
|
||||||
// guidance' from Steve Baker sbaker@link.com
|
// guidance' from Steve Baker sbaker@link.com
|
||||||
int
|
int
|
||||||
fgVIEW::SphereClip( const Point3D& cp, const double radius )
|
FGView::SphereClip( const Point3D& cp, const double radius )
|
||||||
{
|
{
|
||||||
double x1, y1;
|
double x1, y1;
|
||||||
|
|
||||||
|
@ -594,11 +594,15 @@ fgVIEW::SphereClip( const Point3D& cp, const double radius )
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
fgVIEW::~fgVIEW( void ) {
|
FGView::~FGView( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.30 1998/12/09 18:50:28 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.29 1998/12/05 15:54:24 curt
|
// Revision 1.29 1998/12/05 15:54:24 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -45,9 +45,7 @@
|
||||||
|
|
||||||
|
|
||||||
// Define a structure containing view information
|
// Define a structure containing view information
|
||||||
class fgVIEW {
|
class FGView {
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// the current offset from forward for viewing
|
// the current offset from forward for viewing
|
||||||
double view_offset;
|
double view_offset;
|
||||||
|
@ -141,13 +139,18 @@ public:
|
||||||
// Current model view matrix;
|
// Current model view matrix;
|
||||||
GLdouble MODEL_VIEW[16];
|
GLdouble MODEL_VIEW[16];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
fgVIEW( void );
|
FGView( void );
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
~FGView( void );
|
||||||
|
|
||||||
// Initialize a view class
|
// Initialize a view class
|
||||||
void Init( void );
|
void Init( void );
|
||||||
|
|
||||||
void update_globals( FGState *f );
|
void UpdateGlobals( FGState *f );
|
||||||
|
|
||||||
// Basically, this is a modified version of the Mesa gluLookAt()
|
// Basically, this is a modified version of the Mesa gluLookAt()
|
||||||
// function that's been modified slightly so we can capture the
|
// function that's been modified slightly so we can capture the
|
||||||
|
@ -169,18 +172,64 @@ public:
|
||||||
// Update the field of view parameters
|
// Update the field of view parameters
|
||||||
void UpdateFOV( fgOPTIONS *o );
|
void UpdateFOV( fgOPTIONS *o );
|
||||||
|
|
||||||
// Destructor
|
// accessor functions
|
||||||
~fgVIEW( void );
|
inline double get_view_offset() const { return view_offset; }
|
||||||
|
inline void set_view_offset( double a ) { view_offset = a; }
|
||||||
|
inline void inc_view_offset( double amt ) { view_offset += amt; }
|
||||||
|
inline double get_goal_view_offset() const { return goal_view_offset; }
|
||||||
|
inline void set_goal_view_offset( double a) { goal_view_offset = a; }
|
||||||
|
inline bool get_update_fov() const { return update_fov; }
|
||||||
|
inline void set_update_fov(bool value) { update_fov = value; }
|
||||||
|
inline double get_win_ratio() const { return win_ratio; }
|
||||||
|
inline void set_win_ratio( double r ) { win_ratio = r; }
|
||||||
|
inline int get_winWidth() const { return winWidth; }
|
||||||
|
inline void set_winWidth( int w ) { winWidth = w; }
|
||||||
|
inline int get_winHeight() const { return winHeight; }
|
||||||
|
inline void set_winHeight( int h ) { winHeight = h; }
|
||||||
|
inline double get_slope_y() const { return slope_y; }
|
||||||
|
inline double get_slope_x() const { return slope_x; }
|
||||||
|
#if defined( USE_FAST_FOV_CLIP )
|
||||||
|
inline double get_fov_x_clip() const { return fov_x_clip; }
|
||||||
|
inline double get_fov_y_clip() const { return fov_y_clip; }
|
||||||
|
#endif // USE_FAST_FOV_CLIP
|
||||||
|
inline double get_vfc_ratio() const { return vfc_ratio; }
|
||||||
|
inline void set_vfc_ratio(double r) { vfc_ratio = r; }
|
||||||
|
inline int get_tris_rendered() const { return tris_rendered; }
|
||||||
|
inline void set_tris_rendered( int tris) { tris_rendered = tris; }
|
||||||
|
inline Point3D get_abs_view_pos() const { return abs_view_pos; }
|
||||||
|
inline Point3D get_view_pos() const { return view_pos; }
|
||||||
|
inline Point3D get_cur_zero_elev() const { return cur_zero_elev; }
|
||||||
|
inline double *get_to_sun() { return to_sun; }
|
||||||
|
inline void set_to_sun( double x, double y, double z) {
|
||||||
|
to_sun[0] = x;
|
||||||
|
to_sun[1] = y;
|
||||||
|
to_sun[2] = z;
|
||||||
|
}
|
||||||
|
inline double *get_surface_to_sun() { return surface_to_sun; }
|
||||||
|
inline void set_surface_to_sun( double x, double y, double z) {
|
||||||
|
surface_to_sun[0] = x;
|
||||||
|
surface_to_sun[1] = y;
|
||||||
|
surface_to_sun[2] = z;
|
||||||
|
}
|
||||||
|
inline double *get_surface_south() { return surface_south; }
|
||||||
|
inline double *get_surface_east() { return surface_east; }
|
||||||
|
inline double *get_local_up() { return local_up; }
|
||||||
|
inline MAT3mat *get_WORLD_TO_EYE() const { return &WORLD_TO_EYE; }
|
||||||
|
inline GLdouble *get_MODEL_VIEW() { return MODEL_VIEW; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern fgVIEW current_view;
|
extern FGView current_view;
|
||||||
|
|
||||||
|
|
||||||
#endif // _VIEWS_HXX
|
#endif // _VIEWS_HXX
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.17 1998/12/09 18:50:29 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.16 1998/12/05 15:54:25 curt
|
// Revision 1.16 1998/12/05 15:54:25 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -226,6 +226,8 @@ fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
|
||||||
void
|
void
|
||||||
fgMATERIAL::render_fragments()
|
fgMATERIAL::render_fragments()
|
||||||
{
|
{
|
||||||
|
int tris_rendered = current_view.get_tris_rendered();
|
||||||
|
|
||||||
// cout << "rendering " + texture_name + " = " << list_size << "\n";
|
// cout << "rendering " + texture_name + " = " << list_size << "\n";
|
||||||
|
|
||||||
if ( empty() )
|
if ( empty() )
|
||||||
|
@ -251,7 +253,7 @@ fgMATERIAL::render_fragments()
|
||||||
|
|
||||||
for ( ; current != last; ++current ) {
|
for ( ; current != last; ++current ) {
|
||||||
fgFRAGMENT* frag_ptr = *current;
|
fgFRAGMENT* frag_ptr = *current;
|
||||||
current_view.tris_rendered += frag_ptr->num_faces();
|
tris_rendered += frag_ptr->num_faces();
|
||||||
if ( frag_ptr->tile_ptr != last_tile_ptr )
|
if ( frag_ptr->tile_ptr != last_tile_ptr )
|
||||||
{
|
{
|
||||||
// new tile, new translate
|
// new tile, new translate
|
||||||
|
@ -263,6 +265,8 @@ fgMATERIAL::render_fragments()
|
||||||
// printf(" display_list = %d\n", frag_ptr->display_list);
|
// printf(" display_list = %d\n", frag_ptr->display_list);
|
||||||
xglCallList( frag_ptr->display_list );
|
xglCallList( frag_ptr->display_list );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_view.set_tris_rendered( tris_rendered );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,7 +352,8 @@ fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
|
||||||
void
|
void
|
||||||
fgMATERIAL_MGR::render_fragments()
|
fgMATERIAL_MGR::render_fragments()
|
||||||
{
|
{
|
||||||
current_view.tris_rendered = 0;
|
current_view.set_tris_rendered( 0 );
|
||||||
|
|
||||||
iterator last = end();
|
iterator last = end();
|
||||||
for ( iterator current = begin(); current != last; ++current )
|
for ( iterator current = begin(); current != last; ++current )
|
||||||
(*current).second.render_fragments();
|
(*current).second.render_fragments();
|
||||||
|
@ -356,6 +361,10 @@ fgMATERIAL_MGR::render_fragments()
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.12 1998/12/09 18:50:30 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.11 1998/11/07 19:07:12 curt
|
// Revision 1.11 1998/11/07 19:07:12 curt
|
||||||
// Enable release builds using the --without-logging option to the configure
|
// Enable release builds using the --without-logging option to the configure
|
||||||
// script. Also a couple log message cleanups, plus some C to C++ comment
|
// script. Also a couple log message cleanups, plus some C to C++ comment
|
||||||
|
|
|
@ -123,15 +123,12 @@ fgTILECACHE::entry_free( int index )
|
||||||
int
|
int
|
||||||
fgTILECACHE::next_avail( void )
|
fgTILECACHE::next_avail( void )
|
||||||
{
|
{
|
||||||
fgVIEW *v;
|
Point3D delta, abs_view_pos;
|
||||||
Point3D delta;
|
|
||||||
int i;
|
int i;
|
||||||
float max, med, min, tmp;
|
float max, med, min, tmp;
|
||||||
float dist, max_dist;
|
float dist, max_dist;
|
||||||
int max_index;
|
int max_index;
|
||||||
|
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
max_dist = 0.0;
|
max_dist = 0.0;
|
||||||
max_index = 0;
|
max_index = 0;
|
||||||
|
|
||||||
|
@ -140,14 +137,16 @@ fgTILECACHE::next_avail( void )
|
||||||
return(i);
|
return(i);
|
||||||
} else {
|
} else {
|
||||||
// calculate approximate distance from view point
|
// calculate approximate distance from view point
|
||||||
|
abs_view_pos = current_view.get_abs_view_pos();
|
||||||
|
|
||||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||||
"DIST Abs view pos = " << v->abs_view_pos );
|
"DIST Abs view pos = " << abs_view_pos );
|
||||||
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
FG_LOG( FG_TERRAIN, FG_DEBUG,
|
||||||
" ref point = " << tile_cache[i].center );
|
" ref point = " << tile_cache[i].center );
|
||||||
|
|
||||||
delta.setx( fabs(tile_cache[i].center.x() - v->abs_view_pos.x() ) );
|
delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) );
|
||||||
delta.sety( fabs(tile_cache[i].center.y() - v->abs_view_pos.y() ) );
|
delta.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) );
|
||||||
delta.setz( fabs(tile_cache[i].center.z() - v->abs_view_pos.z() ) );
|
delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) );
|
||||||
|
|
||||||
max = delta.x(); med = delta.y(); min = delta.z();
|
max = delta.x(); med = delta.y(); min = delta.z();
|
||||||
if ( max < med ) {
|
if ( max < med ) {
|
||||||
|
@ -182,6 +181,10 @@ fgTILECACHE::~fgTILECACHE( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.21 1998/12/09 18:50:32 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.20 1998/11/09 23:40:49 curt
|
// Revision 1.20 1998/11/09 23:40:49 curt
|
||||||
// Bernie Bright <bbright@c031.aone.net.au> writes:
|
// Bernie Bright <bbright@c031.aone.net.au> writes:
|
||||||
// I've made some changes to the Scenery handling. Basically just tidy ups.
|
// I've made some changes to the Scenery handling. Basically just tidy ups.
|
||||||
|
|
|
@ -133,7 +133,7 @@ double
|
||||||
fgTileMgrCurElev( const fgBUCKET& p ) {
|
fgTileMgrCurElev( const fgBUCKET& p ) {
|
||||||
fgTILE *t;
|
fgTILE *t;
|
||||||
fgFRAGMENT *frag_ptr;
|
fgFRAGMENT *frag_ptr;
|
||||||
Point3D abs_view_pos = current_view.abs_view_pos;
|
Point3D abs_view_pos = current_view.get_abs_view_pos();
|
||||||
Point3D earth_center(0.0);
|
Point3D earth_center(0.0);
|
||||||
Point3D result;
|
Point3D result;
|
||||||
MAT3vec local_up;
|
MAT3vec local_up;
|
||||||
|
@ -471,7 +471,7 @@ static int viewable( const Point3D& cp, double radius ) {
|
||||||
y = cp.y();
|
y = cp.y();
|
||||||
z = cp.z();
|
z = cp.z();
|
||||||
|
|
||||||
mat = (double *)(current_view.WORLD_TO_EYE);
|
mat = (double *)(current_view.get_WORLD_TO_EYE());
|
||||||
|
|
||||||
eye[2] = x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
|
eye[2] = x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
|
||||||
|
|
||||||
|
@ -482,19 +482,21 @@ static int viewable( const Point3D& cp, double radius ) {
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12]) * current_view.slope_x;
|
eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12])
|
||||||
|
* current_view.get_slope_x();
|
||||||
|
|
||||||
// check right and left clip plane (from eye perspective)
|
// check right and left clip plane (from eye perspective)
|
||||||
x1 = radius * current_view.fov_x_clip;
|
x1 = radius * current_view.get_fov_x_clip();
|
||||||
if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) )
|
if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) )
|
||||||
{
|
{
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13]) * current_view.slope_y;
|
eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13])
|
||||||
|
* current_view.get_slope_y();
|
||||||
|
|
||||||
// check bottom and top clip plane (from eye perspective)
|
// check bottom and top clip plane (from eye perspective)
|
||||||
y1 = radius * current_view.fov_y_clip;
|
y1 = radius * current_view.get_fov_y_clip();
|
||||||
if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) )
|
if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) )
|
||||||
{
|
{
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -644,7 +646,7 @@ void fgTileMgrRender( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgTILECACHE *c;
|
fgTILECACHE *c;
|
||||||
fgTILE *t;
|
fgTILE *t;
|
||||||
fgVIEW *v;
|
FGView *v;
|
||||||
Point3D frag_offset;
|
Point3D frag_offset;
|
||||||
fgFRAGMENT *frag_ptr;
|
fgFRAGMENT *frag_ptr;
|
||||||
fgMATERIAL *mtl_ptr;
|
fgMATERIAL *mtl_ptr;
|
||||||
|
@ -684,7 +686,7 @@ void fgTileMgrRender( void ) {
|
||||||
|
|
||||||
// Calculate the model_view transformation matrix for this tile
|
// Calculate the model_view transformation matrix for this tile
|
||||||
// This is equivalent to doing a glTranslatef(x, y, z);
|
// This is equivalent to doing a glTranslatef(x, y, z);
|
||||||
t->UpdateViewMatrix( v->MODEL_VIEW );
|
t->UpdateViewMatrix( v->get_MODEL_VIEW() );
|
||||||
|
|
||||||
// xglPushMatrix();
|
// xglPushMatrix();
|
||||||
// xglTranslatef(t->offset.x, t->offset.y, t->offset.z);
|
// xglTranslatef(t->offset.x, t->offset.y, t->offset.z);
|
||||||
|
@ -731,9 +733,9 @@ void fgTileMgrRender( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (drawn + culled) > 0 ) {
|
if ( (drawn + culled) > 0 ) {
|
||||||
v->vfc_ratio = (double)culled / (double)(drawn + culled);
|
v->set_vfc_ratio( (double)culled / (double)(drawn + culled) );
|
||||||
} else {
|
} else {
|
||||||
v->vfc_ratio = 0.0;
|
v->set_vfc_ratio( 0.0 );
|
||||||
}
|
}
|
||||||
// printf("drawn = %d culled = %d saved = %.2f\n", drawn, culled,
|
// printf("drawn = %d culled = %d saved = %.2f\n", drawn, culled,
|
||||||
// v->vfc_ratio);
|
// v->vfc_ratio);
|
||||||
|
@ -748,6 +750,10 @@ void fgTileMgrRender( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.51 1998/12/09 18:50:33 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.50 1998/12/06 13:51:25 curt
|
// Revision 1.50 1998/12/06 13:51:25 curt
|
||||||
// Turned "struct fgWEATHER" into "class FGWeather".
|
// Turned "struct fgWEATHER" into "class FGWeather".
|
||||||
//
|
//
|
||||||
|
|
|
@ -91,7 +91,6 @@ void fgLIGHT::Init( void ) {
|
||||||
void fgLIGHT::Update( void ) {
|
void fgLIGHT::Update( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgTIME *t;
|
fgTIME *t;
|
||||||
fgVIEW *v;
|
|
||||||
// if the 4th field is 0.0, this specifies a direction ...
|
// if the 4th field is 0.0, this specifies a direction ...
|
||||||
GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
|
GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||||
// base sky color
|
// base sky color
|
||||||
|
@ -102,7 +101,6 @@ void fgLIGHT::Update( void ) {
|
||||||
|
|
||||||
f = current_aircraft.fdm_state;
|
f = current_aircraft.fdm_state;
|
||||||
t = &cur_time_params;
|
t = &cur_time_params;
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
FG_LOG( FG_EVENT, FG_INFO, "Updating light parameters." );
|
FG_LOG( FG_EVENT, FG_INFO, "Updating light parameters." );
|
||||||
|
|
||||||
|
@ -151,11 +149,9 @@ void fgLIGHT::Update( void ) {
|
||||||
// calculate fog color adjusted for sunrise/sunset effects
|
// calculate fog color adjusted for sunrise/sunset effects
|
||||||
void fgLIGHT::UpdateAdjFog( void ) {
|
void fgLIGHT::UpdateAdjFog( void ) {
|
||||||
FGState *f;
|
FGState *f;
|
||||||
fgVIEW *v;
|
|
||||||
double sun_angle_deg, rotation, param1[3], param2[3];
|
double sun_angle_deg, rotation, param1[3], param2[3];
|
||||||
|
|
||||||
f = current_aircraft.fdm_state;
|
f = current_aircraft.fdm_state;
|
||||||
v = ¤t_view;
|
|
||||||
|
|
||||||
FG_LOG( FG_EVENT, FG_DEBUG, "Updating adjusted fog parameters." );
|
FG_LOG( FG_EVENT, FG_DEBUG, "Updating adjusted fog parameters." );
|
||||||
|
|
||||||
|
@ -164,7 +160,8 @@ void fgLIGHT::UpdateAdjFog( void ) {
|
||||||
|
|
||||||
// first determine the difference between our view angle and local
|
// first determine the difference between our view angle and local
|
||||||
// direction to the sun
|
// direction to the sun
|
||||||
rotation = -(sun_rotation + FG_PI) - (f->get_Psi() - v->view_offset) ;
|
rotation = -(sun_rotation + FG_PI)
|
||||||
|
- (f->get_Psi() - current_view.get_view_offset());
|
||||||
while ( rotation < 0 ) {
|
while ( rotation < 0 ) {
|
||||||
rotation += FG_2PI;
|
rotation += FG_2PI;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +214,10 @@ fgLIGHT::~fgLIGHT( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.24 1998/12/09 18:50:35 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.23 1998/12/05 15:54:30 curt
|
// Revision 1.23 1998/12/05 15:54:30 curt
|
||||||
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
// Renamed class fgFLIGHT to class FGState as per request by JSB.
|
||||||
//
|
//
|
||||||
|
|
|
@ -329,8 +329,8 @@ static void fgSunPositionGST(double gst, double *lon, double *lat) {
|
||||||
void fgUpdateSunPos( void ) {
|
void fgUpdateSunPos( void ) {
|
||||||
fgLIGHT *l;
|
fgLIGHT *l;
|
||||||
fgTIME *t;
|
fgTIME *t;
|
||||||
fgVIEW *v;
|
FGView *v;
|
||||||
MAT3vec nup, nsun, v0;
|
MAT3vec nup, nsun, v0, surface_to_sun;
|
||||||
Point3D p, rel_sunpos;
|
Point3D p, rel_sunpos;
|
||||||
double dot, east_dot;
|
double dot, east_dot;
|
||||||
double sun_gd_lat, sl_radius;
|
double sun_gd_lat, sl_radius;
|
||||||
|
@ -371,7 +371,7 @@ void fgUpdateSunPos( void ) {
|
||||||
// l->sun_vec[2]);
|
// l->sun_vec[2]);
|
||||||
|
|
||||||
// calculate the sun's relative angle to local up
|
// calculate the sun's relative angle to local up
|
||||||
MAT3_COPY_VEC(nup, v->local_up);
|
MAT3_COPY_VEC(nup, v->get_local_up());
|
||||||
nsun[0] = l->fg_sunpos.x();
|
nsun[0] = l->fg_sunpos.x();
|
||||||
nsun[1] = l->fg_sunpos.y();
|
nsun[1] = l->fg_sunpos.y();
|
||||||
nsun[2] = l->fg_sunpos.z();
|
nsun[2] = l->fg_sunpos.z();
|
||||||
|
@ -383,22 +383,23 @@ void fgUpdateSunPos( void ) {
|
||||||
// l->sun_angle);
|
// l->sun_angle);
|
||||||
|
|
||||||
// calculate vector to sun's position on the earth's surface
|
// calculate vector to sun's position on the earth's surface
|
||||||
rel_sunpos = l->fg_sunpos - (v->view_pos + scenery.center);
|
rel_sunpos = l->fg_sunpos - (v->get_view_pos() + scenery.center);
|
||||||
v->to_sun[0] = rel_sunpos.x();
|
v->set_to_sun( rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() );
|
||||||
v->to_sun[1] = rel_sunpos.y();
|
|
||||||
v->to_sun[2] = rel_sunpos.z();
|
|
||||||
// printf( "Vector to sun = %.2f %.2f %.2f\n",
|
// printf( "Vector to sun = %.2f %.2f %.2f\n",
|
||||||
// v->to_sun[0], v->to_sun[1], v->to_sun[2]);
|
// v->to_sun[0], v->to_sun[1], v->to_sun[2]);
|
||||||
|
|
||||||
// make a vector to the current view position
|
// make a vector to the current view position
|
||||||
MAT3_SET_VEC(v0, v->view_pos.x(), v->view_pos.y(), v->view_pos.z());
|
Point3D view_pos = v->get_view_pos();
|
||||||
|
MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
|
||||||
|
|
||||||
// Given a vector from the view position to the point on the
|
// Given a vector from the view position to the point on the
|
||||||
// earth's surface the sun is directly over, map into onto the
|
// earth's surface the sun is directly over, map into onto the
|
||||||
// local plane representing "horizontal".
|
// local plane representing "horizontal".
|
||||||
map_vec_onto_cur_surface_plane(v->local_up, v0, v->to_sun,
|
map_vec_onto_cur_surface_plane( v->get_local_up(), v0, v->get_to_sun(),
|
||||||
v->surface_to_sun);
|
surface_to_sun );
|
||||||
MAT3_NORMALIZE_VEC(v->surface_to_sun, ntmp);
|
MAT3_NORMALIZE_VEC(surface_to_sun, ntmp);
|
||||||
|
v->set_surface_to_sun( surface_to_sun[0], surface_to_sun[1],
|
||||||
|
surface_to_sun[2] );
|
||||||
// printf("Surface direction to sun is %.2f %.2f %.2f\n",
|
// printf("Surface direction to sun is %.2f %.2f %.2f\n",
|
||||||
// v->surface_to_sun[0], v->surface_to_sun[1], v->surface_to_sun[2]);
|
// v->surface_to_sun[0], v->surface_to_sun[1], v->surface_to_sun[2]);
|
||||||
// printf("Should be close to zero = %.2f\n",
|
// printf("Should be close to zero = %.2f\n",
|
||||||
|
@ -407,13 +408,13 @@ void fgUpdateSunPos( void ) {
|
||||||
// calculate the angle between v->surface_to_sun and
|
// calculate the angle between v->surface_to_sun and
|
||||||
// v->surface_east. We do this so we can sort out the acos()
|
// v->surface_east. We do this so we can sort out the acos()
|
||||||
// ambiguity. I wish I could think of a more efficient way ... :-(
|
// ambiguity. I wish I could think of a more efficient way ... :-(
|
||||||
east_dot = MAT3_DOT_PRODUCT(v->surface_to_sun, v->surface_east);
|
east_dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_east() );
|
||||||
// printf(" East dot product = %.2f\n", east_dot);
|
// printf(" East dot product = %.2f\n", east_dot);
|
||||||
|
|
||||||
// calculate the angle between v->surface_to_sun and
|
// calculate the angle between v->surface_to_sun and
|
||||||
// v->surface_south. this is how much we have to rotate the sky
|
// v->surface_south. this is how much we have to rotate the sky
|
||||||
// for it to align with the sun
|
// for it to align with the sun
|
||||||
dot = MAT3_DOT_PRODUCT(v->surface_to_sun, v->surface_south);
|
dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_south() );
|
||||||
// printf(" Dot product = %.2f\n", dot);
|
// printf(" Dot product = %.2f\n", dot);
|
||||||
if ( east_dot >= 0 ) {
|
if ( east_dot >= 0 ) {
|
||||||
l->sun_rotation = acos(dot);
|
l->sun_rotation = acos(dot);
|
||||||
|
@ -426,6 +427,10 @@ void fgUpdateSunPos( void ) {
|
||||||
|
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.18 1998/12/09 18:50:36 curt
|
||||||
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
||||||
|
// members private and make required accessor functions.
|
||||||
|
//
|
||||||
// Revision 1.17 1998/11/09 23:41:53 curt
|
// Revision 1.17 1998/11/09 23:41:53 curt
|
||||||
// Log message clean ups.
|
// Log message clean ups.
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Reference in a new issue