From: david Date: Wed, 27 Mar 2002 14:52:19 +0000 (+0000) Subject: Viewer patches from Jim Wilson: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=38c705b6c024ba39516cafab55a6e37dab4128ef;p=flightgear.git Viewer patches from Jim Wilson: Think my brain is getting clogged with matrices :-). Well I've got the funky orientation offset bug out of the model code. In the process the model.cxx got optimized a bit. At some point we'll need to liberate model.cxx from the viewer class, but it is no longer hard coded to access the "pilot view" to get it's data. Instead it uses whatever the "current" view happens to be. I may try and do that final bit of having models rotate independant of the view tomorrow night, or start right in on the viewmgr and get a tower view up and running. You guys have any preference? My brother's family is coming to visit for a few days so what I don't get done tomorrow night probably won't get done until after the weekend. --- diff --git a/src/Main/model.cxx b/src/Main/model.cxx index 213cc41df..7eabd4e0f 100644 --- a/src/Main/model.cxx +++ b/src/Main/model.cxx @@ -25,6 +25,8 @@ extern ssgRoot * scene; // FIXME: from main.cxx FGAircraftModel current_model; // FIXME: add to globals + + static ssgEntity * find_named_node (ssgEntity * node, const string &name) { @@ -43,6 +45,7 @@ find_named_node (ssgEntity * node, const string &name) return 0; } + FGAircraftModel::FGAircraftModel () : _model(0), _selector(new ssgSelector), @@ -148,7 +151,8 @@ FGAircraftModel::unbind () void FGAircraftModel::update (int dt) { - sgMat4 VIEW_ROT; + sgMat4 MODEL_ROT, LOCAL; + sgMat4 sgTRANS; _current_timestamp.stamp(); long elapsed_ms = (_current_timestamp - _last_timestamp) / 1000; @@ -163,65 +167,41 @@ FGAircraftModel::update (int dt) do_animation(_animations[i], elapsed_ms); _selector->select(true); - FGViewer *pilot_view = - (FGViewer *)globals->get_viewmgr()->get_view( 0 ); - - sgMat4 sgTRANS; - // FIXME: this needs to be unlinked from the viewer - // The lon/lat/alt should come from properties and the - // calculation for relative position should probably be - // added to SimGear. - sgMakeTransMat4( sgTRANS, pilot_view->getRelativeViewPos() ); - - sgVec3 ownship_up; - sgSetVec3( ownship_up, 0.0, 0.0, 1.0); - - sgMat4 sgROT; - sgMakeRotMat4( sgROT, -90.0, ownship_up ); + FGViewer *current_view = + (FGViewer *)globals->get_viewmgr()->get_view( view_number ); - sgMat4 sgTUX; - sgCopyMat4( sgTUX, sgROT ); - - if (view_number == 0) { - - // FIXME: This needs to be unlinked from the viewer - // The lon/lat/alt should come from properties and the - // calculation for relative position should probably be - // added to SimGear. - // Note that the function for building the LOCAL matrix - // or redone using plib. Should probably be moved to Simgear. - // (cockpit_ROT = LOCAL from viewer). - sgMat4 tmpROT; - sgCopyMat4( tmpROT, pilot_view->get_COCKPIT_ROT() ); - sgMat4 cockpit_ROT; - sgCopyMat4( cockpit_ROT, tmpROT ); - - // Make the Cockpit rotation matrix (just juggling the vectors). - cockpit_ROT[0][0] = tmpROT[1][0]; // right - cockpit_ROT[0][1] = tmpROT[1][1]; - cockpit_ROT[0][2] = tmpROT[1][2]; - cockpit_ROT[1][0] = tmpROT[2][0]; // forward - cockpit_ROT[1][1] = tmpROT[2][1]; - cockpit_ROT[1][2] = tmpROT[2][2]; - cockpit_ROT[2][0] = tmpROT[0][0]; // view_up - cockpit_ROT[2][1] = tmpROT[0][1]; - cockpit_ROT[2][2] = tmpROT[0][2]; - - sgPostMultMat4( sgTUX, cockpit_ROT ); - sgPostMultMat4( sgTUX, sgTRANS ); - - } else { - // FIXME: Model rotation need to be unlinked from the viewer. - // When the cockpit rotation gets removed from viewer - // then it'll be easy to apply offsets and get the equivelant - // of this "VIEW_ROT" thing. - sgCopyMat4( VIEW_ROT, pilot_view->get_VIEW_ROT()); - sgPostMultMat4( sgTUX, VIEW_ROT ); - sgPostMultMat4( sgTUX, sgTRANS ); - } + // FIXME: this class needs to be unlinked from the viewer + // get transform for current position in the world... + sgMakeTransMat4( sgTRANS, current_view->getRelativeViewPos() ); + + // get a copy of the LOCAL rotation from the current view... + sgCopyMat4( LOCAL, current_view->get_LOCAL_ROT() ); + + // Make the MODEL Rotation (just reordering the LOCAL matrix + // and flipping the model over on its feet)... + MODEL_ROT[0][0] = -LOCAL[2][0]; + MODEL_ROT[0][1] = -LOCAL[2][1]; + MODEL_ROT[0][2] = -LOCAL[2][2]; + MODEL_ROT[0][3] = SG_ZERO; + MODEL_ROT[1][0] = LOCAL[1][0]; + MODEL_ROT[1][1] = LOCAL[1][1]; + MODEL_ROT[1][2] = LOCAL[1][2]; + MODEL_ROT[1][3] = SG_ZERO; + MODEL_ROT[2][0] = LOCAL[0][0]; + MODEL_ROT[2][1] = LOCAL[0][1]; + MODEL_ROT[2][2] = LOCAL[0][2]; + MODEL_ROT[2][3] = SG_ZERO; + + // add the position data to the matrix + MODEL_ROT[3][0] = SG_ZERO; + MODEL_ROT[3][1] = SG_ZERO; + MODEL_ROT[3][2] = SG_ZERO; + MODEL_ROT[3][3] = SG_ONE; + + sgPostMultMat4( MODEL_ROT, sgTRANS ); sgCoord tuxpos; - sgSetCoord( &tuxpos, sgTUX ); + sgSetCoord( &tuxpos, MODEL_ROT ); _position->setTransform( &tuxpos ); } } @@ -405,3 +385,5 @@ FGAircraftModel::Animation::setRotation() // end of model.cxx + + diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index 0fc291b54..b5a90a470 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -46,6 +46,150 @@ #include "viewer.hxx" +////////////////////////////////////////////////////////////////// +// 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 +static void MakeVIEW_OFFSET( sgMat4 dst, + const float angle1, const sgVec3 axis1, + const float angle2, const sgVec3 axis2 ) +{ + // make rotmatrix1 from angle and axis + float s = (float) sin ( angle1 ) ; + float c = (float) cos ( angle1 ) ; + float t = SG_ONE - c ; + + sgMat3 mat1; + float tmp = t * axis1[0]; + mat1[0][0] = tmp * axis1[0] + c ; + mat1[0][1] = tmp * axis1[1] + s * axis1[2] ; + mat1[0][2] = tmp * axis1[2] - s * axis1[1] ; + + tmp = t * axis1[1]; + mat1[1][0] = tmp * axis1[0] - s * axis1[2] ; + mat1[1][1] = tmp * axis1[1] + c ; + mat1[1][2] = tmp * axis1[2] + s * axis1[0] ; + + tmp = t * axis1[2]; + mat1[2][0] = tmp * axis1[0] + s * axis1[1] ; + mat1[2][1] = tmp * axis1[1] - s * axis1[0] ; + mat1[2][2] = tmp * axis1[2] + c ; + + // make rotmatrix2 from angle and axis + s = (float) sin ( angle2 ) ; + c = (float) cos ( angle2 ) ; + t = SG_ONE - c ; + + sgMat3 mat2; + tmp = t * axis2[0]; + mat2[0][0] = tmp * axis2[0] + c ; + mat2[0][1] = tmp * axis2[1] + s * axis2[2] ; + mat2[0][2] = tmp * axis2[2] - s * axis2[1] ; + + tmp = t * axis2[1]; + mat2[1][0] = tmp * axis2[0] - s * axis2[2] ; + mat2[1][1] = tmp * axis2[1] + c ; + mat2[1][2] = tmp * axis2[2] + s * axis2[0] ; + + tmp = t * axis2[2]; + mat2[2][0] = tmp * axis2[0] + s * axis2[1] ; + mat2[2][1] = tmp * axis2[1] - s * axis2[0] ; + mat2[2][2] = tmp * axis2[2] + c ; + + // multiply matrices + for ( int j = 0 ; j < 3 ; j++ ) { + dst[0][j] = mat2[0][0] * mat1[0][j] + + mat2[0][1] * mat1[1][j] + + mat2[0][2] * mat1[2][j]; + + dst[1][j] = mat2[1][0] * mat1[0][j] + + mat2[1][1] * mat1[1][j] + + mat2[1][2] * mat1[2][j]; + + dst[2][j] = mat2[2][0] * mat1[0][j] + + mat2[2][1] * mat1[1][j] + + mat2[2][2] * mat1[2][j]; + } + // fill in 4x4 matrix elements + dst[0][3] = SG_ZERO; + dst[1][3] = SG_ZERO; + 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; +} + +// 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. //////////////////////////////////////////////////////////////////////// @@ -85,13 +229,6 @@ FGViewer::~FGViewer( void ) { void FGViewer::init () { - if ( _type == FG_LOOKAT ) { - set_reverse_view_offset(true); - } - - if ( _type == FG_RPH ) { - set_reverse_view_offset(false); - } } void @@ -370,7 +507,10 @@ FGViewer::recalc () _roll_deg * SG_DEGREES_TO_RADIANS, -_heading_deg * SG_DEGREES_TO_RADIANS); // Adjust LOCAL to current world_up vector (adjustment for planet location) - sgPostMultMat4( LOCAL, UP ); + MakeWithWorldUp( LOCAL, UP, LOCAL ); + // copy the LOCAL matrix to COCKPIT_ROT for publication... + sgCopyMat4( LOCAL_ROT, LOCAL ); + // make sg vectors view up, right and forward vectors from LOCAL sgSetVec3( _view_up, LOCAL[0][0], LOCAL[0][1], LOCAL[0][2] ); sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] ); @@ -384,32 +524,32 @@ FGViewer::recalc () - // generate the heading offset matrix using heading_offset angle(s) + // Eye rotations. + // Looking up/down left/right in pilot view (lookfrom mode) + // or Floating Rotatation around the object in chase view (lookat mode). + // Generate the offset matrix to be applied using offset angles: if (_type == FG_LOOKAT) { // Note that when in "chase view" the offset is in relation to the // orientation heading (_heading_deg) of the model being looked at as // it is used to rotate around the model. - sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg -_heading_deg, _world_up ); + MakeVIEW_OFFSET( VIEW_OFFSET, + (_heading_offset_deg - _heading_deg) * SG_DEGREES_TO_RADIANS, _world_up, + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); } if (_type == FG_RPH) { - // generate the view offset matrix using orientation offset (heading) - sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg, _view_up ); + // generate the view offset matrix using orientation offsets + MakeVIEW_OFFSET( VIEW_OFFSET, + _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up, + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); } - // create a tilt matrix using orientation offset (pitch) - sgMakeRotMat4( VIEW_PITCHOFFSET, _pitch_offset_deg, right ); - - sgCopyMat4(VIEW_OFFSET, VIEW_HEADINGOFFSET); - sgPreMultMat4(VIEW_OFFSET, VIEW_PITCHOFFSET); - if (_type == FG_LOOKAT) { // transfrom "offset" and "orientation offset" to vector sgXformVec3( position_offset, position_offset, UP ); - sgXformVec3( position_offset, position_offset, VIEW_HEADINGOFFSET ); - sgXformPnt3( position_offset, position_offset, VIEW_PITCHOFFSET ); + sgXformVec3( position_offset, position_offset, VIEW_OFFSET ); sgVec3 object_pos, eye_pos; // copy to coordinates to object... @@ -447,9 +587,6 @@ FGViewer::recalc () VIEW[3][2] = _view_pos[2]; VIEW[3][3] = 1.0f; - - // copy the LOCAL matrix to COCKPIT_ROT for publication... - sgCopyMat4( COCKPIT_ROT, LOCAL ); } // the VIEW matrix includes both rotation and translation. Let's @@ -614,35 +751,4 @@ FGViewer::update (int dt) } } -void FGViewer::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 ; -} - diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index aeff7b110..88b327419 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -208,12 +208,9 @@ public: // Matrices... virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; } virtual const sgVec4 *get_VIEW_ROT() { if ( _dirty ) { recalc(); } return VIEW_ROT; } - virtual const sgVec4 *get_COCKPIT_ROT() { if ( _dirty ) { recalc(); } return COCKPIT_ROT; } + virtual const sgVec4 *get_LOCAL_ROT() { if ( _dirty ) { recalc(); } return LOCAL_ROT; } virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; } - // Public flags... - virtual bool get_reverse_view_offset() const { return _reverse_view_offset; } - ////////////////////////////////////////////////////////////////////// // Part 4: frustrum data setters and getters ////////////////////////////////////////////////////////////////////// @@ -307,7 +304,7 @@ private: // sgVec3 _view_forward; // sg versions of our friendly matrices - sgMat4 VIEW, VIEW_ROT, UP, COCKPIT_ROT; + sgMat4 VIEW, VIEW_ROT, UP, LOCAL_ROT; sgMat4 LOCAL, TRANS, LARC_TO_SSG; // Transformation matrix for the view direction offset relative to @@ -324,16 +321,6 @@ private: inline void set_dirty() { _dirty = true; } inline void set_clean() { _dirty = false; } - // from lookat - void fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center, - const sgVec3 up ); - - // from rph - void fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 ); - void fgMakeLOCAL( sgMat4 dst, const double Theta, - const double Phi, const double Psi); - - // add to _heading_offset_deg inline void incHeadingOffset_deg( double amt ) { set_dirty(); @@ -350,37 +337,15 @@ private: _reverse_view_offset = val; } +}; -// public: - - - ////////////////////////////////////////////////////////////////////// - // setter functions - ////////////////////////////////////////////////////////////////////// - -// inline void set_sea_level_radius( double r ) { -// // data should be in meters from the center of the earth -// set_dirty(); -// sea_level_radius = r; -// } +#endif // _VIEWER_HXX - ////////////////////////////////////////////////////////////////////// - // accessor functions - ////////////////////////////////////////////////////////////////////// -// inline int get_type() const { return _type ; } -// inline int is_a( int t ) const { return get_type() == t ; } -// inline bool is_dirty() const { return _dirty; } -// inline double get_sea_level_radius() const { return sea_level_radius; } - ////////////////////////////////////////////////////////////////////// - // derived values accessor functions - ////////////////////////////////////////////////////////////////////// -}; -#endif // _VIEWER_HXX diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 8ca1f584e..110a06f59 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -148,18 +148,20 @@ FGViewMgr::update (int dt) sgVec3 *pPO = PilotOffsetGet(); sgVec3 zPO; sgCopyVec3( zPO, *pPO ); - chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] ); + chase_view->setPositionOffsets(zPO[1], zPO[0], zPO[2] ); chase_view->setOrientation( fgGetDouble("/orientation/roll-deg"), fgGetDouble("/orientation/pitch-deg"), fgGetDouble("/orientation/heading-deg")); - + chase_view ->setPosition( + fgGetDouble("/position/longitude-deg"), + fgGetDouble("/position/latitude-deg"), + fgGetDouble("/position/altitude-ft")); chase_view ->setTargetPosition( fgGetDouble("/position/longitude-deg"), fgGetDouble("/position/latitude-deg"), fgGetDouble("/position/altitude-ft")); - chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] ); // Update the current view do_axes(); @@ -369,3 +371,5 @@ FGViewMgr::do_axes () + + diff --git a/src/Time/light.cxx b/src/Time/light.cxx index 0841cfbfb..a38526051 100644 --- a/src/Time/light.cxx +++ b/src/Time/light.cxx @@ -186,9 +186,6 @@ void fgLIGHT::UpdateAdjFog( void ) { // direction to the sun rotation = -(sun_rotation + SGD_PI) - (f->get_Psi() - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS); - if ( globals->get_current_view()->get_reverse_view_offset() ) { - rotation += SGD_PI; - } while ( rotation < 0 ) { rotation += SGD_2PI; } @@ -242,3 +239,4 @@ fgLIGHT::~fgLIGHT( void ) { +