+ if ( _from_model ) {
+ SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+ _position = placement->getPosition();
+ _heading_deg = placement->getHeadingDeg();
+ _pitch_deg = placement->getPitchDeg();
+ _roll_deg = placement->getRollDeg();
+ } else {
+ // update from our own data, just the rotation here...
+ dampEyeData(_roll_deg, _pitch_deg, _heading_deg);
+ }
+ SGQuatd geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg,
+ _pitch_deg,
+ _roll_deg);
+ SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(_position);
+
+ // the rotation offset, don't know why heading is negative here ...
+ mViewOffsetOr =
+ SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg,
+ _roll_offset_deg);
+
+ // Offsets to the eye position
+ SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
+ SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
+ SGVec3d eyeCart = SGVec3d::fromGeod(_position);
+ eyeCart += (ec2eye*mViewOffsetOr).backTransform(eyeOff);
+
+ SGVec3d atCart = SGVec3d::fromGeod(_target);
+
+ // add target offsets to at_position...
+ SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(),
+ -_target_offset_m.y());
+ target_pos_off = (geodTargetHlOr*geodTargetOr).backTransform(target_pos_off);
+ atCart += target_pos_off;
+ eyeCart += target_pos_off;
+
+ // Compute the eyepoints orientation and position
+ // wrt the earth centered frame - that is global coorinates
+ _absolute_view_pos = eyeCart;
+
+ // the view direction
+ SGVec3d dir = normalize(atCart - eyeCart);
+ // the up directon
+ SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, -1));
+ // rotate -dir to the 2-th unit vector
+ // rotate up to 1-th unit vector
+ // Note that this matches the OpenGL camera coordinate system
+ // with x-right, y-up, z-back.
+ mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);