1
0
Fork 0

Jim Wilson:

These are the updates for the View manager properties.  Removed the last of
items (within the viewer/viewmgr) hard coded to view number.  Added support
for per view configuration of ground level nearplane value.  Tower views look
very nice with little or no z-buffer problem in the models.  Pilot offset
dialog can be used to move eye in all views.
This commit is contained in:
curt 2002-04-18 16:51:47 +00:00
parent e5abcd1ef1
commit 71598c12f8
9 changed files with 322 additions and 232 deletions

View file

@ -690,10 +690,10 @@ static GlBitmap *b1 = NULL;
extern FGInterface cur_view_fdm;
GLubyte *hiResScreenCapture( int multiplier )
{
float oldfov = fgGetDouble("/sim/field-of-view");
float oldfov = fgGetDouble("/sim/current-view/field-of-view");
float fov = oldfov / multiplier;
FGViewer *v = globals->get_current_view();
fgSetDouble("/sim/field-of-view", fov);
fgSetDouble("/sim/current-view/field-of-view", fov);
fgInitVisuals();
int cur_width = fgGetInt("/sim/startup/xsize");
int cur_height = fgGetInt("/sim/startup/ysize");
@ -712,7 +712,7 @@ GLubyte *hiResScreenCapture( int multiplier )
b1->copyBitmap( &b2, cur_width*x, cur_height*y );
}
}
fgSetDouble("/sim/field-of-view", oldfov);
fgSetDouble("/sim/current-view/field-of-view", oldfov);
return b1->getBitmap();
}
#endif
@ -1064,4 +1064,3 @@ void guiInit()
guiToggleMenu(); // Menu off by default
}
}

View file

@ -35,9 +35,9 @@ public:
float max = 100.0f, float min = 0.0f);
~FloatSlider () {;}
static void adj( puObject *);
static void adj( puObject *);
void updateText() {
sprintf( _text, "%05.2f", MyValue );
}
@ -52,6 +52,9 @@ public:
// adjust the TmpValue back to 0 to 1 range of pui widget
void setTmp() { TmpValue += 0.0f; }
void incTmp() { TmpValue += 0.0001f; setTmp(); }
void decTmp() { TmpValue -= 0.0001f; setTmp(); }
// adjust actual "setting" value back to fraction for pui widget
void init( float f ) {
if (f > maxValue) f = maxValue;
@ -69,7 +72,7 @@ public:
void FloatSlider::adj( puObject *hs )
{
FloatSlider *slider = (FloatSlider *)hs->getUserData();
FloatSlider *slider = (FloatSlider *)hs;
slider->getValue ( slider->getTmp() );
slider->setTmp();
slider->set();
@ -79,17 +82,15 @@ void FloatSlider::adj( puObject *hs )
FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
float max, float min ) : puSlider( x, y, sz, FALSE )
{
setUserData( this );
maxValue = max;
minValue = min;
origValue = f;
init(f);
setDelta ( 0.01 );
setCBMode ( PUSLIDER_DELTA ) ;
setCallback ( adj ) ;
strcpy ( _title, title);
setLabel ( _title );
setLabelPlace ( PUPLACE_LEFT );
setLabelPlace ( PUPLACE_LEFT );
setLegend(_text);
// setLegendPlace( PUPLACE_RIGHT );
}
@ -131,6 +132,9 @@ public:
// adjust the TmpValue back to 0 to 1 range of pui widget
void setTmp() { TmpValue += 0.5f; }
void incTmp() { TmpValue += 0.0001f; setTmp(); }
void decTmp() { TmpValue -= 0.0001f; setTmp(); }
// adjust actual "setting" value back to fraction for pui widget
// double the range from -max <-> max
@ -150,7 +154,7 @@ public:
void FloatDial::adj( puObject *hs )
{
FloatDial *dial = (FloatDial *)hs->getUserData();
FloatDial *dial = (FloatDial *)hs;
dial->getValue ( dial->getTmp() );
dial->setTmp();
dial->set();
@ -160,14 +164,12 @@ void FloatDial::adj( puObject *hs )
FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
float max, float min ) : puDial( x, y, sz )
{
setUserData( this );
maxValue = max;
minValue = min;
origValue = f;
init(f);
setDelta ( 0.01 );
setCBMode ( PUSLIDER_DELTA ) ;
setCallback ( adj ) ;
strcpy ( _title, title);
setLabel ( _title );
setLabelPlace ( PUPLACE_LEFT );
@ -180,6 +182,10 @@ FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
class sgVec3Slider : public puDialogBox
{
static void handle_arrow(puObject *p_obj);
static void heading_adj(puObject *p_obj);
static void pitch_adj(puObject *p_obj);
static void radius_adj(puObject *p_obj);
static void goAway(puObject *p_obj);
static void reset(puObject *p_obj);
static void cancel(puObject *p_obj);
@ -193,6 +199,8 @@ protected:
puOneShot *OkButton;
puOneShot *ResetButton;
puOneShot *CancelButton;
puArrowButton *right_arrow;
puArrowButton *left_arrow;
sgVec3 Vec, SaveVec;
public:
@ -201,10 +209,11 @@ public:
const char *title = "Vector Adjuster",
const char *Xtitle = "Heading",
const char *Ytitle = "Pitch",
const char *Ztitle = "Radius" );
const char *Ztitle = "Radius " );
~sgVec3Slider () {;}
// calc the property Vec with the actual point on sphere
void setVec()
{
@ -238,16 +247,19 @@ public:
};
// class constructor
sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 cart, const char *title,
const char *Xtitle,
const char *Ytitle,
const char *Ztitle ): puDialogBox ( x, y )
{
puFont LegendFont, LabelFont;
puGetDefaultFonts ( &LegendFont, &LabelFont );
int fudge = 20;
HeadingPitchRadiusFromVec3( Vec, cart);
sgVec3 vec;
sgSetVec3(vec, Vec[0], Vec[1], Vec[2]);
int labelW = LabelFont.getStringWidth(Xtitle);
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
@ -284,12 +296,26 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
/* heading */
HS0 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[0], Xtitle, 180.0f, -180.0f );
dialer_x = dialer_x + 170;
HS0->setUserData (this);
HS0->setCallback ( heading_adj ) ;
/* pitch */
HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f );
HS1->setUserData (this);
HS1->setCallback ( pitch_adj ) ;
/* radius */
HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );
HS2 = new FloatSlider ( slider_x+20, slider_y, slider_width-40, vec[2], Ztitle, 100.0f, 0.0f );
HS2->setUserData (this);
HS2->setCallback ( radius_adj );
right_arrow = new puArrowButton ( slider_x + slider_width - 20, slider_y + 1, slider_x + slider_width, slider_y+21, PUARROW_RIGHT ) ;
right_arrow->setUserData ( HS2 ) ;
right_arrow->setCallback ( handle_arrow ) ;
left_arrow = new puArrowButton ( slider_x, slider_y + 1, slider_x+20, slider_y+21, PUARROW_LEFT ) ;
left_arrow->setUserData ( HS2 ) ;
left_arrow->setCallback ( handle_arrow ) ;
TitleText = new puText( 130, DialogHeight - 40);
TitleText->setLabel("Pilot Offset");
@ -305,14 +331,49 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
CancelButton-> setLegend ( gui_msg_CANCEL );
CancelButton-> setCallback ( cancel );
ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
ResetButton-> setUserData( this );
ResetButton-> setLegend ( gui_msg_RESET );
ResetButton-> setCallback ( reset );
// renabling this button requires binding in the sim/view[?]/config/?-offset-m values
// ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
// ResetButton-> setUserData( this );
// ResetButton-> setLegend ( gui_msg_RESET );
// ResetButton-> setCallback ( reset );
FG_FINALIZE_PUI_DIALOG( this );
}
void sgVec3Slider::handle_arrow(puObject *arrow)
{
FloatSlider *slider = (FloatSlider *) arrow->getUserData();
if (((puArrowButton *)arrow)->getArrowType() == PUARROW_RIGHT)
slider->incTmp();
else
slider->decTmp();
slider->set();
slider->init( slider->get() );
sgVec3Slider *me = (sgVec3Slider *)slider->getUserData();
me->setVec();
};
void sgVec3Slider::heading_adj(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
me->HS0->adj((puObject *)me ->HS0 );
me->setVec();
};
void sgVec3Slider::pitch_adj(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
me->HS1->adj((puObject *)me ->HS1 );
me->setVec();
};
void sgVec3Slider::radius_adj(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
me ->HS2-> adj((puObject *)me ->HS2 );
me->setVec();
};
void sgVec3Slider::goAway(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
@ -343,6 +404,23 @@ void sgVec3Slider::cancel(puObject *p_obj)
void sgVec3Slider::adjust(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
heading_adj( me );
pitch_adj( me );
radius_adj( me );
sgVec3 cart;
sgSetVec3(cart,
fgGetFloat("/sim/current-view/x-offset-m"),
fgGetFloat("/sim/current-view/y-offset-m"),
fgGetFloat("/sim/current-view/z-offset-m")
);
HeadingPitchRadiusFromVec3( me->Vec, cart);
me -> getHS0() -> init(me->Vec[0]);
me -> getHS1() -> init(me->Vec[1]);
me -> getHS2() -> init(me->Vec[2]);
me -> getHS0() -> adj((puObject *)me -> getHS0());
me -> getHS1() -> adj((puObject *)me -> getHS1());
me -> getHS2() -> adj((puObject *)me -> getHS2());
@ -360,30 +438,25 @@ void sgVec3SliderAdjust( puObject *p_obj )
static puObject *PO_vec = 0;
void PilotOffsetInit() {
sgVec3 v;
sgSetVec3(v,
fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"),
fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"),
fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m")
sgVec3 cart;
sgSetVec3(cart,
fgGetFloat("/sim/current-view/x-offset-m"),
fgGetFloat("/sim/current-view/y-offset-m"),
fgGetFloat("/sim/current-view/z-offset-m")
);
PilotOffsetInit(v);
PilotOffsetInit(cart);
}
void PilotOffsetInit( sgVec3 vec )
void PilotOffsetInit( sgVec3 cart )
{
// Only one of these things for now
if( PO_vec == 0 ) {
/* make change so this gets done once for each vector */
fgSetFloat("/sim/view[1]/current/pilot-offset/heading-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"));
fgSetFloat("/sim/view[1]/current/pilot-offset/pitch-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"));
fgSetFloat("/sim/view[1]/current/pilot-offset/radius-m",fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m"));
sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
sgVec3Slider *PO = new sgVec3Slider ( 200, 200, cart, "Pilot Offset" );
PO_vec = PO;
// Bindings for Pilot Offset
fgTie("/sim/view[1]/current/pilot-offset/heading-deg", getPilotOffsetHeadingDeg, setPilotOffsetHeadingDeg);
fgTie("/sim/view[1]/current/pilot-offset/pitch-deg", getPilotOffsetPitchDeg, setPilotOffsetPitchDeg);
fgTie("/sim/view[1]/current/pilot-offset/radius-m", getPilotOffsetRadiusM, setPilotOffsetRadiusM);
fgTie("/sim/current-view/x-offset-m", getPilotXOffset, setPilotXOffset);
fgTie("/sim/current-view/y-offset-m", getPilotYOffset, setPilotYOffset);
fgTie("/sim/current-view/z-offset-m", getPilotZOffset, setPilotZOffset);
}
}
@ -393,8 +466,8 @@ void PilotOffsetAdjust( puObject * )
PilotOffsetInit();
}
sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
me -> stashVec();
me -> adjust( me );
me -> stashVec();
FG_PUSH_PUI_DIALOG( me );
}
@ -416,9 +489,11 @@ float PilotOffsetGetSetting(int opt)
PilotOffsetInit();
}
sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
if( opt == 0 ) setting = me -> getHS0() -> get();
if( opt == 1 ) setting = me -> getHS1() -> get();
if( opt == 2 ) setting = me-> getHS2() -> get();
sgVec3 vec;
sgCopyVec3(vec, (float *) me->getVec());
if( opt == 0 ) setting = vec[0];
if( opt == 1 ) setting = vec[1];
if( opt == 2 ) setting = vec[2];
return( setting );
}
@ -429,9 +504,18 @@ void PilotOffsetSet(int opt, float setting)
PilotOffsetInit();
}
sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
if( opt == 0 ) me -> getHS0() -> init( setting );
if( opt == 1 ) me -> getHS1() -> init( setting );
if( opt == 2 ) me-> getHS2() -> init( setting );
sgVec3 HPR;
sgVec3 vec;
sgCopyVec3(vec, (float *) me->getVec());
if( opt == 0 ) vec[0] = setting;
if( opt == 1 ) vec[1] = setting;
if( opt == 2 ) vec[2] = setting;
HeadingPitchRadiusFromVec3 ( HPR, vec );
me -> getHS0() -> init( HPR[0] );
me -> getHS1() -> init( HPR[1] );
me -> getHS2() -> init( HPR[2] );
me -> stashVec();
}
@ -440,7 +524,7 @@ void PilotOffsetSet(int opt, float setting)
// input Pitch == latitude of point on sphere
// input Radius == radius of sphere
#define MIN_VIEW_OFFSET 5.0
#define MIN_VIEW_OFFSET 0.001
void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,
float radius )
{
@ -475,3 +559,44 @@ float radius )
vec3[1] = (SGfloat)( sh * cp ) * radius ; // Y
vec3[0] = (SGfloat)( sp ) * radius ; // Z
}
// Convert to speherical coordinates for the dials
void HeadingPitchRadiusFromVec3 ( sgVec3 hpr, sgVec3 vec3 )
{
double x = vec3[0];
double y = vec3[1];
double z = vec3[2];
double Zx;
double Pr;
if (z == 0.0f) {
hpr[0] = 0;
hpr[1] = 0;
hpr[2] = 0;
} else {
if (fabs(y) < 0.001f)
y == 0.001f;
Zx = sqrt(y*y + z*z);
hpr[2] = sqrt(x*x + y*y + z*z);
Pr = Zx / hpr[2];
if (Pr > 1.0f)
hpr[1] = 0.0f;
else
hpr[1] = acos(Pr) * SGD_RADIANS_TO_DEGREES;
if (x < 0.0f)
hpr[1] *= -SGD_ONE;
if (z < 0.0f) {
hpr[0] = (SGD_PI - asin(y/Zx)) * SGD_RADIANS_TO_DEGREES;
} else {
hpr[0] = asin(y/Zx) * SGD_RADIANS_TO_DEGREES;
if (hpr[0] > 180) {
hpr[0] = 180 - hpr[0];
}
}
}
}

View file

@ -18,6 +18,7 @@ void PilotOffsetInit();
void PilotOffsetInit( sgVec3 vec );
void PilotOffsetAdjust( puObject * );
void Vec3FromHeadingPitchRadius( sgVec3 vec3, float heading, float pitch, float radius );
void HeadingPitchRadiusFromVec3( sgVec3 hpr, sgVec3 vec3 );
//void PilotOffsetGet( float *po );
sgVec3 *PilotOffsetGet();
void PilotOffsetSet( int opt, float setting);
@ -28,40 +29,39 @@ float PilotOffsetGetSetting( int opt );
/* binding functions for chase view offset */
static void
setPilotOffsetHeadingDeg (float value)
setPilotXOffset (float value)
{
PilotOffsetSet(0, value);
}
static float
getPilotOffsetHeadingDeg ()
getPilotXOffset ()
{
return( PilotOffsetGetSetting(0) );
}
static void
setPilotOffsetPitchDeg (float value)
setPilotYOffset (float value)
{
PilotOffsetSet(1, value);
}
static float
getPilotOffsetPitchDeg ()
getPilotYOffset ()
{
return( PilotOffsetGetSetting(1) );
}
static void
setPilotOffsetRadiusM (float value)
setPilotZOffset (float value)
{
PilotOffsetSet(2, value);
}
static float
getPilotOffsetRadiusM ()
getPilotZOffset ()
{
return( PilotOffsetGetSetting(2) );
}

View file

@ -407,6 +407,8 @@ void fgRenderFrame( void ) {
= fgGetNode("/position/latitude-deg");
static const SGPropertyNode *altitude
= fgGetNode("/position/altitude-ft");
static const SGPropertyNode *groundlevel_nearplane
= fgGetNode("/sim/current-view/ground-level-nearplane-m");
// Update the default (kludged) properties.
fgUpdateProps();
@ -592,15 +594,11 @@ void fgRenderFrame( void ) {
double agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
- scenery.get_cur_elev();
// if (fgGetBool("/sim/view/internal"))
// ssgSetNearFar( 0.2f, 120000.0f );
// else if ( agl > 10.0)
if ( agl > 10.0 ) {
scene_nearplane = 10.0f;
scene_farplane = 120000.0f;
} else {
scene_nearplane = 0.5f;
scene_nearplane = groundlevel_nearplane->getDoubleValue();
scene_farplane = 120000.0f;
}

View file

@ -177,7 +177,7 @@ fgSetDefaults ()
fgSetInt("/sim/startup/ysize", 600);
fgSetInt("/sim/rendering/bits-per-pixel", 16);
fgSetString("/sim/view-mode", "pilot");
fgSetDouble("/sim/view/offset-deg", 0);
fgSetDouble("/sim/current-view/heading-offset-deg", 0);
fgSetDouble("/environment/visibility-m", 20000);
// HUD options
@ -427,7 +427,7 @@ parse_fov( const string& arg ) {
if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
fgSetDouble("/sim/field-of-view", fov);
fgSetDouble("/sim/current-view/field-of-view", fov);
// printf("parse_fov(): result = %.4f\n", fov);
@ -886,7 +886,8 @@ parse_option (const string& arg)
(FGViewer *)globals->get_viewmgr()->get_view( 0 );
pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
pilot_view->setGoalHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
fgSetDouble("/sim/view/offset-deg", default_view_offset * SGD_RADIANS_TO_DEGREES );
fgSetDouble( "/sim/current-view/heading-offset-deg",
default_view_offset * SGD_RADIANS_TO_DEGREES );
// $$$ end - added VS Renganathan, 14 Oct 2K
} else if ( arg.find( "--visibility=" ) == 0 ) {
fgSetDouble("/environment/visibility-m", atof(arg.substr(13)));
@ -1290,6 +1291,3 @@ fgUsage ()
<< " instances allowed." << endl
<< endl;
}

View file

@ -52,37 +52,6 @@
// Norman's Optimized matrix rotators! //
//////////////////////////////////////////////////////////////////
static void fgMakeLOCAL( sgMat4 dst, const double Theta,
const double Phi, const double Psi)
{
SGfloat cosTheta = (SGfloat) cos(Theta);
SGfloat sinTheta = (SGfloat) sin(Theta);
SGfloat cosPhi = (SGfloat) cos(Phi);
SGfloat sinPhi = (SGfloat) sin(Phi);
SGfloat sinPsi = (SGfloat) sin(Psi) ;
SGfloat cosPsi = (SGfloat) cos(Psi) ;
dst[0][0] = cosPhi * cosTheta;
dst[0][1] = sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
dst[0][2] = sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
dst[0][3] = SG_ZERO;
dst[1][0] = -sinPhi * cosTheta;
dst[1][1] = cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
dst[1][2] = cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
dst[1][3] = SG_ZERO ;
dst[2][0] = sinTheta;
dst[2][1] = cosTheta * -sinPsi;
dst[2][2] = cosTheta * cosPsi;
dst[2][3] = SG_ZERO;
dst[3][0] = SG_ZERO;
dst[3][1] = SG_ZERO;
dst[3][2] = SG_ZERO;
dst[3][3] = SG_ONE ;
}
// Since these are pure rotation matrices we can save some bookwork
// by considering them to be 3x3 until the very end -- NHV
@ -156,48 +125,13 @@ static void MakeVIEW_OFFSET( sgMat4 dst,
dst[3][3] = SG_ONE;
}
// Taking advantage of the 3x3 nature of this -- NHV
inline static void MakeWithWorldUp( sgMat4 dst, const sgMat4 UP, const sgMat4 LOCAL )
{
sgMat4 tmp;
float a = UP[0][0];
float b = UP[1][0];
float c = UP[2][0];
tmp[0][0] = a*LOCAL[0][0] + b*LOCAL[0][1] + c*LOCAL[0][2] ;
tmp[1][0] = a*LOCAL[1][0] + b*LOCAL[1][1] + c*LOCAL[1][2] ;
tmp[2][0] = a*LOCAL[2][0] + b*LOCAL[2][1] + c*LOCAL[2][2] ;
tmp[3][0] = SG_ZERO ;
a = UP[0][1];
b = UP[1][1];
c = UP[2][1];
tmp[0][1] = a*LOCAL[0][0] + b*LOCAL[0][1] + c*LOCAL[0][2] ;
tmp[1][1] = a*LOCAL[1][0] + b*LOCAL[1][1] + c*LOCAL[1][2] ;
tmp[2][1] = a*LOCAL[2][0] + b*LOCAL[2][1] + c*LOCAL[2][2] ;
tmp[3][1] = SG_ZERO ;
a = UP[0][2];
c = UP[2][2];
tmp[0][2] = a*LOCAL[0][0] + c*LOCAL[0][2] ;
tmp[1][2] = a*LOCAL[1][0] + c*LOCAL[1][2] ;
tmp[2][2] = a*LOCAL[2][0] + c*LOCAL[2][2] ;
tmp[3][2] = SG_ZERO ;
tmp[0][3] = SG_ZERO ;
tmp[1][3] = SG_ZERO ;
tmp[2][3] = SG_ZERO ;
tmp[3][3] = SG_ONE ;
sgCopyMat4(dst, tmp);
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGViewer.
////////////////////////////////////////////////////////////////////////
// Constructor
FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index ):
FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index, double x_offset_m, double y_offset_m, double z_offset_m, double near_m ):
_scaling_type(FG_SCALING_MAX),
_fov_deg(55.0),
_dirty(true),
@ -210,9 +144,6 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool
_roll_deg(0),
_pitch_deg(0),
_heading_deg(0),
_x_offset_m(0),
_y_offset_m(0),
_z_offset_m(0),
_heading_offset_deg(0),
_pitch_offset_deg(0),
_roll_offset_deg(0),
@ -225,6 +156,10 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool
_from_model_index = from_model_index;
_at_model = at_model;
_at_model_index = at_model_index;
_x_offset_m = x_offset_m;
_y_offset_m = y_offset_m;
_z_offset_m = z_offset_m;
_ground_level_nearplane_m = near_m;
//a reasonable guess for init, so that the math doesn't blow up
}
@ -551,6 +486,7 @@ FGViewer::recalc ()
sgVec3 minus_z, right, forward, tilt;
sgMat4 tmpROT; // temp rotation work matrices
sgVec3 eye_pos, at_pos;
sgVec3 position_offset; // eye position offsets (xyz)
// The position vectors originate from the view point or target location
// depending on the type of view.
@ -628,11 +564,6 @@ FGViewer::recalc ()
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] );
// create the (xyz) eye Position offsets Vector
sgVec3 position_offset;
sgSetVec3( position_offset, -_z_offset_m, _x_offset_m, _y_offset_m );
if (_type == FG_LOOKAT) {
// Note that when in "lookat" view the "world up" vector is always applied
@ -644,10 +575,10 @@ FGViewer::recalc ()
(_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up,
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
// Eye Position Offsets to vector
sgXformVec3( position_offset, position_offset, UP );
// add in the Orientation Offsets here
sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
sgXformVec3( position_offset, position_offset, UP);
sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
// add the Position offsets from object to the eye position
@ -671,17 +602,26 @@ FGViewer::recalc ()
_heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up,
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
// Eye Position Offsets to vector
sgXformVec3( position_offset, position_offset, LOCAL);
// add the offsets including rotations to the translation vector
sgAddVec3( _view_pos, position_offset );
// Make the VIEW matrix.
sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO);
sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO);
sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO);
sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE);
// rotate matrix to get a matrix to apply Eye Position Offsets
sgMat4 VIEW_UP; // L0 forward L1 right L2 up
sgCopyVec4(VIEW_UP[0], LOCAL[1]);
sgCopyVec4(VIEW_UP[1], LOCAL[2]);
sgCopyVec4(VIEW_UP[2], LOCAL[0]);
sgZeroVec4(VIEW_UP[3]);
// Eye Position Offsets to vector
sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
sgXformVec3( position_offset, position_offset, VIEW_UP);
// add the offsets including rotations to the translation vector
sgAddVec3( _view_pos, position_offset );
// multiply the OFFSETS (for heading and pitch) into the VIEW
sgPostMultMat4(VIEW, VIEW_OFFSET);
@ -832,10 +772,3 @@ FGViewer::update (int dt)
}
}
}

View file

@ -62,7 +62,9 @@ public:
};
// Constructor
FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index );
FGViewer( fgViewType Type, bool from_model, int from_model_index,
bool at_model, int at_model_index, double x_offset_m,
double y_offset_m, double z_offset_m, double near_m );
// Destructor
virtual ~FGViewer( void );
@ -216,7 +218,7 @@ public:
virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
//////////////////////////////////////////////////////////////////////
// Part 4: frustrum data setters and getters
// Part 4: View and frustrum data setters and getters
//////////////////////////////////////////////////////////////////////
virtual void set_fov( double fov_deg ) {
@ -231,6 +233,11 @@ public:
}
virtual double get_aspect_ratio() const { return _aspect_ratio; }
virtual double getNear_m () const { return _ground_level_nearplane_m; }
inline void setNear_m (double near_m) {
_ground_level_nearplane_m = near_m;
}
//////////////////////////////////////////////////////////////////////
// Part 5: misc setters and getters
//////////////////////////////////////////////////////////////////////
@ -281,6 +288,9 @@ private:
double _goal_pitch_offset_deg;
double _goal_heading_offset_deg;
// used to set nearplane when at ground level for this view
double _ground_level_nearplane_m;
fgViewType _type;
fgScalingType _scaling_type;

View file

@ -54,6 +54,8 @@ FGViewMgr::init ()
bool at_model = false;
int from_model_index = 0;
int at_model_index = 0;
double x_offset_m, y_offset_m, z_offset_m;
double near_m;
for (int i = 0; i < fgGetInt("/sim/number-views"); i++) {
viewpath = "/sim/view";
@ -94,12 +96,33 @@ FGViewMgr::init ()
}
}
nodepath = viewpath;
nodepath += "/config/x-offset-m";
x_offset_m = fgGetDouble(nodepath.c_str());
nodepath = viewpath;
nodepath += "/config/y-offset-m";
y_offset_m = fgGetDouble(nodepath.c_str());
nodepath = viewpath;
nodepath += "/config/z-offset-m";
z_offset_m = fgGetDouble(nodepath.c_str());
nodepath = viewpath;
nodepath += "/config/ground-level-nearplane-m";
near_m = fgGetDouble(nodepath.c_str());
// supporting two types now "lookat" = 1 and "lookfrom" = 0
if ( strcmp("lookat",strdata.c_str()) == 0 )
add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index, at_model, at_model_index ));
add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index,
at_model, at_model_index, x_offset_m, y_offset_m,
z_offset_m, near_m ));
else
add_view(new FGViewer ( FG_LOOKFROM, from_model, from_model_index, false, 0 ));
add_view(new FGViewer ( FG_LOOKFROM, from_model, from_model_index, false,
0, x_offset_m, y_offset_m, z_offset_m, near_m ));
}
copyToCurrent();
}
typedef double (FGViewMgr::*double_getter)() const;
@ -107,36 +130,33 @@ typedef double (FGViewMgr::*double_getter)() const;
void
FGViewMgr::bind ()
{
// FIXME:
// need to redo these bindings to the new locations (move to viewer?)
fgTie("/sim/view/offset-deg", this,
// these are bound to the current view properties
fgTie("/sim/current-view/heading-offset-deg", this,
&FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg);
fgSetArchivable("/sim/view/offset-deg");
fgTie("/sim/view/goal-offset-deg", this,
fgSetArchivable("/sim/current-view/heading-offset-deg");
fgTie("/sim/current-view/goal-heading-offset-deg", this,
&FGViewMgr::getGoalViewOffset_deg, &FGViewMgr::setGoalViewOffset_deg);
fgSetArchivable("/sim/view/goal-offset-deg");
fgTie("/sim/view/tilt-deg", this,
fgSetArchivable("/sim/current-view/goal-heading-offset-deg");
fgTie("/sim/current-view/pitch-offset-deg", this,
&FGViewMgr::getViewTilt_deg, &FGViewMgr::setViewTilt_deg);
fgSetArchivable("/sim/view/tilt-deg");
fgTie("/sim/view/goal-tilt-deg", this,
fgSetArchivable("/sim/current-view/pitch-offset-deg");
fgTie("/sim/current-view/goal-pitch-offset-deg", this,
&FGViewMgr::getGoalViewTilt_deg, &FGViewMgr::setGoalViewTilt_deg);
fgSetArchivable("/sim/view/goal-tilt-deg");
fgTie("/sim/view/pilot/x-offset-m", this,
&FGViewMgr::getPilotXOffset_m, &FGViewMgr::setPilotXOffset_m);
fgSetArchivable("/sim/view/pilot/x-offset-m");
fgTie("/sim/view/pilot/y-offset-m", this,
&FGViewMgr::getPilotYOffset_m, &FGViewMgr::setPilotYOffset_m);
fgSetArchivable("/sim/view/pilot/y-offset-m");
fgTie("/sim/view/pilot/z-offset-m", this,
&FGViewMgr::getPilotZOffset_m, &FGViewMgr::setPilotZOffset_m);
fgSetArchivable("/sim/view/pilot/z-offset-m");
fgTie("/sim/field-of-view", this,
&FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
fgSetArchivable("/sim/field-of-view");
fgTie("/sim/view/axes/long", this,
fgSetArchivable("/sim/current-view/goal-pitch-offset-deg");
fgTie("/sim/current-view/axes/long", this,
(double_getter)0, &FGViewMgr::setViewAxisLong);
fgTie("/sim/view/axes/lat", this,
fgTie("/sim/current-view/axes/lat", this,
(double_getter)0, &FGViewMgr::setViewAxisLat);
fgTie("/sim/current-view/field-of-view", this,
&FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
fgSetArchivable("/sim/current-view/field-of-view");
fgTie("/sim/current-view/ground-level-nearplane-m", this,
&FGViewMgr::getNear_m, &FGViewMgr::setNear_m);
fgSetArchivable("/sim/current-view/ground-level-nearplane-m");
}
void
@ -144,16 +164,13 @@ FGViewMgr::unbind ()
{
// FIXME:
// need to redo these bindings to the new locations (move to viewer?)
fgUntie("/sim/view/offset-deg");
fgUntie("/sim/view/goal-offset-deg");
fgUntie("/sim/view/tilt-deg");
fgUntie("/sim/view/goal-tilt-deg");
fgUntie("/sim/view/pilot/x-offset-m");
fgUntie("/sim/view/pilot/y-offset-m");
fgUntie("/sim/view/pilot/z-offset-m");
fgUntie("/sim/current-view/heading-offset-deg");
fgUntie("/sim/current-view/goal-heading-offset-deg");
fgUntie("/sim/current-view/pitch-offset-deg");
fgUntie("/sim/current-view/goal-pitch-offset-deg");
fgUntie("/sim/field-of-view");
fgUntie("/sim/view/axes/long");
fgUntie("/sim/view/axes/lat");
fgUntie("/sim/current-view/axes/long");
fgUntie("/sim/current-view/axes/lat");
}
void
@ -235,27 +252,25 @@ FGViewMgr::update (int dt)
loop_view->set_dirty();
}
}
setPilotXOffset_m(fgGetDouble("/sim/current-view/x-offset-m"));
setPilotYOffset_m(fgGetDouble("/sim/current-view/y-offset-m"));
setPilotZOffset_m(fgGetDouble("/sim/current-view/z-offset-m"));
// Set up the chase view
// FIXME:
// Gotta change sgVec3Slider so that it takes xyz values as inputs
// instead of spherical coordinates.
FGViewer *chase_view = (FGViewer *)get_view( 1 );
// get xyz Position offsets directly from GUI/sgVec3Slider
// FIXME: change GUI/sgVec3Slider to store the xyz in properties
// it would probably be faster than the way PilotOffsetGet()
// triggers a recalc all the time.
sgVec3 *pPO = PilotOffsetGet();
sgVec3 zPO;
sgCopyVec3( zPO, *pPO );
chase_view->setPositionOffsets(zPO[1], zPO[2], zPO[0] );
// Update the current view
// Update the current view
do_axes();
view->update(dt);
double tmp;
}
void
FGViewMgr::copyToCurrent()
{
fgSetDouble("/sim/current-view/x-offset-m", getPilotXOffset_m());
fgSetDouble("/sim/current-view/y-offset-m", getPilotYOffset_m());
fgSetDouble("/sim/current-view/z-offset-m", getPilotZOffset_m());
}
double
FGViewMgr::getViewOffset_deg () const
{
@ -323,10 +338,9 @@ FGViewMgr::setGoalViewTilt_deg (double tilt)
double
FGViewMgr::getPilotXOffset_m () const
{
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
return ((FGViewer *)pilot_view)->getXOffset_m();
const FGViewer * view = get_current_view();
if (view != 0) {
return ((FGViewer *)view)->getXOffset_m();
} else {
return 0;
}
@ -335,20 +349,18 @@ FGViewMgr::getPilotXOffset_m () const
void
FGViewMgr::setPilotXOffset_m (double x)
{
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
pilot_view->setXOffset_m(x);
FGViewer * view = get_current_view();
if (view != 0) {
view->setXOffset_m(x);
}
}
double
FGViewMgr::getPilotYOffset_m () const
{
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
return ((FGViewer *)pilot_view)->getYOffset_m();
const FGViewer * view = get_current_view();
if (view != 0) {
return ((FGViewer *)view)->getYOffset_m();
} else {
return 0;
}
@ -357,20 +369,18 @@ FGViewMgr::getPilotYOffset_m () const
void
FGViewMgr::setPilotYOffset_m (double y)
{
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
pilot_view->setYOffset_m(y);
FGViewer * view = get_current_view();
if (view != 0) {
view->setYOffset_m(y);
}
}
double
FGViewMgr::getPilotZOffset_m () const
{
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
return ((FGViewer *)pilot_view)->getZOffset_m();
const FGViewer * view = get_current_view();
if (view != 0) {
return ((FGViewer *)view)->getZOffset_m();
} else {
return 0;
}
@ -379,10 +389,9 @@ FGViewMgr::getPilotZOffset_m () const
void
FGViewMgr::setPilotZOffset_m (double z)
{
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
pilot_view->setZOffset_m(z);
FGViewer * view = get_current_view();
if (view != 0) {
view->setZOffset_m(z);
}
}
@ -401,6 +410,21 @@ FGViewMgr::setFOV_deg (double fov)
view->set_fov(fov);
}
double
FGViewMgr::getNear_m () const
{
const FGViewer * view = get_current_view();
return (view == 0 ? 0.5f : view->getNear_m());
}
void
FGViewMgr::setNear_m (double near_m)
{
FGViewer * view = get_current_view();
if (view != 0)
view->setNear_m(near_m);
}
void
FGViewMgr::setViewAxisLong (double axis)
{
@ -456,4 +480,3 @@ FGViewMgr::do_axes ()
get_current_view()->setGoalHeadingOffset_deg(viewDir);
}

View file

@ -93,6 +93,7 @@ public:
if ( current >= (int)views.size() ) {
current = 0;
}
copyToCurrent();
return views[current];
}
inline FGViewer *prev_view() {
@ -134,8 +135,11 @@ private:
void setPilotZOffset_m (double z);
double getFOV_deg () const;
void setFOV_deg (double fov);
double getNear_m () const;
void setNear_m (double near_m);
void setViewAxisLong (double axis);
void setViewAxisLat (double axis);
void copyToCurrent ();
typedef vector < FGViewer * > viewer_list;
viewer_list views;